home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / mm / mm-ccmd-0.91-20031009.tar.gz / mm-ccmd-0.91-20031009.tar / work / ccmd / ccmdmd.dos < prev    next >
Text File  |  1990-12-18  |  10KB  |  376 lines

  1. /*
  2.  Copyright (c) 1986, 1990 by The Trustees of Columbia University in
  3.  the City of New York.  Permission is granted to any individual or
  4.  institution to use, copy, or redistribute this software so long as it
  5.  is not sold for profit, provided this copyright notice is retained.
  6.  
  7.  Author: Andrew Lowry
  8. */
  9.  
  10. /* Machine dependent code for systems running under MS-DOS.
  11. ** Assumes ANSI.SYS has been installed as an installable device
  12. ** driver.  For any version or compiler peculiarities, use 
  13. ** preprocessor conditionals, but PLEASE -- do not nest
  14. ** conditionals!
  15. */
  16.  
  17. #include "ccmd.h"        /* get ccmd symbols */
  18. #include "cmfncs.h"        /* and internal symbols */
  19.  
  20.  
  21.  
  22. /* cmrpjmp
  23. **
  24. ** Purpose:
  25. **   Automatic reparse handler, installed via the cmsetrp macro from
  26. **   ccmd.h.  If this handler is installed in a CSB for which a reparse
  27. **   is needed, it will perform a longjmp to restart execution at the
  28. **   point following the installing cmsetrp invocation.  This point
  29. **   should be following the call to cmini that set up parsing for
  30. **   the current command line, and before the comnd call for the first
  31. **   field in the command.
  32. **
  33. ** Input arguments: None
  34. ** Output arguments: None
  35. ** Returns: Nothing
  36. **/
  37.  
  38.  
  39. jmp_buf cmrpjb;            /* global jump buffer for autoreparse */
  40.  
  41. cmrpjmp()
  42. {
  43. #ifdef LATTICE
  44.   longjmp(&cmrpjb,1);        /* do the jump */
  45. #else
  46.   longjmp(cmrpjb,1);
  47. #endif
  48.   return(CMxNOAR);        /* if it returns, it failed */
  49. }
  50.  
  51.  
  52.  
  53. /* cmerjmp
  54. **
  55. ** Purpose:
  56. **   Automatic parse error handler, much like the automatic reparse
  57. **   handler described above.  This macro should be invoked just prior
  58. **   to issuing a prompt.  When a parsing error subsequently occurs
  59. **   (that is, the parse function is about to return anything but
  60. **   CMxOK), cmperr will be called to print the error, and then
  61. **   execution will jump back to the site of this macro.  When the
  62. **   automatic error handler is installed, the user program can
  63. **   ignore the codes returned by parse, since they will always be
  64. **   CMxOK.
  65. **
  66. **   Note: Reparse situations will be handled by the error handler if
  67. **   no reparse handler has been installed.
  68. **
  69. ** Input arguments: None.
  70. ** Output arguments: None.
  71. ** Returns: Nothing.
  72. **/
  73.  
  74. jmp_buf cmerjb;                /* global jump buffer */
  75.  
  76. cmerjmp(ret)
  77. int ret;                /* code that triggered the handler */
  78. {
  79.   cmperr(ret);                /* issue error message */
  80. #ifdef LATTICE
  81.   longjmp(&cmerjb,1);            /* take the jump */
  82. #else
  83.   longjmp(cmerjb,1);
  84. #endif
  85.   return(CMxNOAE);            /* failed */
  86. }
  87.  
  88. cmerjnp(ret)
  89. int ret;                /* code that triggered the handler */
  90. {
  91. #ifdef LATTICE
  92.   longjmp(&cmerjb,1);            /* take the jump */
  93. #else
  94.   longjmp(cmerjb,1);
  95. #endif
  96.   return(CMxNOAE);            /* failed */
  97. }
  98.  
  99.  
  100. /*
  101.  * if handling nonblocking I/O, and a BLOCKING error comes up
  102.  * Then jump to the point set with a cmsetbl() call.
  103.  * The user then could wait for input.
  104.  */
  105.  
  106. jmp_buf cmbljb;                /* global jump buffer */
  107.  
  108. cmbljmp(ret)
  109. int ret;                /* code that triggered the handler */
  110. {
  111.   /*
  112.    * how to check for a blocking error here?
  113.    */
  114.   return(ret);                /* for now, ignore */
  115. #ifdef LATTICE
  116.   longjmp(&cmbljb,1);            /* take the jump */
  117. #else
  118.   longjmp(cmbljb,1);            /* take the jump */
  119. #endif
  120.   return(CMxNOAE);            /* failed */
  121. }
  122.  
  123.  
  124.  
  125. /*
  126. ** Machine-dependent IO routines... In each case, if the file descriptor
  127. ** argument is the special value CONSOLE, the IO is done to the console
  128. ** using Lattice C's direct console I/O routines.  If the file descriptor
  129. ** is not CONSOLE but nevertheless refers to the console, the direct
  130. ** console I/O operations will also be used.  Any other file descriptor
  131. ** is assumed NOT to refer to a terminal, so no echoing will be performed.
  132. ** In this case, the user program may want to set CM_TTY and/or CM_CRT 
  133. ** in order to cause normal terminal handling.  If CRT is set in this
  134. ** case, a dumb crt will be assumed, which does automatic wraparound
  135. ** at the right border and which has no screen functions other than
  136. ** character output, carriage return, linefeed, backspace, and
  137. ** destructive space.
  138. **/
  139.  
  140. static int console;            /* TRUE if source is console */
  141.  
  142. /* cmgetc - get a character from the input source.  Return std return code */
  143.  
  144. int
  145. cmgetc(c,fd)
  146. char *c;            /* pointer where input char is placed */
  147. FILE *fd;            /* input filedesc */
  148. {
  149.   int cc;            /* int returned by system routines */
  150.  
  151.   if (console) {
  152.     *c = getch();
  153.     return(CMxOK);
  154.   }
  155.   if (cmcsb._cmoj != NULL)
  156.     fflush(cmcsb._cmoj);
  157.   if (fd == NULL)
  158.     return(CMxEOF);
  159.   *c = getc(fd);
  160.   if (*c == EOF)
  161.     return(CMxEOF);
  162.   return(CMxOK);
  163. }
  164.  
  165. /* cmputc - Output a single character to the terminal */
  166.  
  167. cmputc(c,fd)
  168. char c;                /* character to output */
  169. FILE *fd;            /* input filedesc */
  170. {
  171.   if (console) {
  172.     if (c == '\n')
  173.       putch('\r');
  174.     putch(c);
  175.   }
  176.   else {
  177.     if (fd != NULL) {
  178.       putc(c,fd);
  179.       if (c == '\n')
  180.     fflush(fd);
  181.     }
  182.   }
  183. }
  184.  
  185. /* cmputs - Output null-terminated string to the terminal */
  186.  
  187. cmputs(s,fd)
  188. char *s;            /* string to output */
  189. FILE *fd;            /* output filedesc */
  190. {
  191.   while(*s != NULL) {
  192.     cmputc(*s,fd);
  193.     *s++;
  194.   }
  195. }
  196.  
  197. /* cmcr - Move to the beginning of the current line */
  198.  
  199. cmcr(fd)
  200. FILE *fd;            /* input filedesc */
  201. {
  202.   cmputc(RETURN,fd);        /* output a carriage return */
  203. }
  204.  
  205. /* cmnl - Output a newline sequence to the command stream */
  206.  
  207. cmnl(fd)
  208. FILE *fd;            /* input filedesc */
  209. {
  210.   cmputc(NEWLINE,fd);        /* just a newline character */
  211. }
  212.  
  213. /* cmflsh - flush output on fd */
  214. cmflsh(fd)
  215. FILE *fd;
  216. {
  217.   if (fd != NULL)
  218.     fflush(fd);
  219. }
  220.  
  221. /* cmwrap - Make sure the cursor wraps when it is required */
  222.  
  223. cmwrap(fd)
  224. FILE *fd;
  225. {
  226.                 /* This happens for console automatically */
  227.                 /* and we assume the same for other devices */
  228. }
  229.  
  230. /* cmcls - Clear the screen.  Only invoked if source is a CRT.  Return
  231. ** TRUE iff we think the operation succeeded.
  232. **/
  233.  
  234. cmcls()
  235. {
  236.   if (console)
  237.     cputs("\033[2J");        /* home and clear screen: ESC [ 2 J */
  238.   else
  239.     cmputc(FORMFEED);        /* for other terminal try a formfeed */
  240.   return(TRUE);            /* assume it worked */
  241. }
  242.  
  243. /* cmceol - Clear to end of line.  Only invoked on a CRT.  Return
  244. ** TRUE iff we think we succeeded.
  245. **/
  246.  
  247. cmceol()
  248. {
  249.   if (console) {
  250.     cputs("\033[K");        /* erase to end-of-line: ESC [ k */
  251.     return(TRUE);
  252.   }
  253.   else
  254.     return(FALSE);        /* say we can't do it on other terminals */
  255. }
  256.  
  257.  
  258. /* cmupl - Moves up one line in the display without changing column
  259. ** position.  Should not wrap to bottom of screen or cause destructive
  260. ** downward scrolling.  Only invoked on a CRT.  Returns TRUE iff we
  261. ** think the operation succeeded.
  262. **/
  263.  
  264. cmupl()
  265. {
  266.   if (console) {
  267.     cputs("\033[A");        /* up one line: ESC [ A */
  268.     return(TRUE);
  269.   }
  270.   else
  271.     return(FALSE);        /* assume other terminals are incapable */
  272. }
  273.  
  274. /* cmcpos - Returns current column position on display.  If the
  275. ** command source is not the console, the column position currently
  276. ** stored in the CSB is returned.
  277. **/
  278.  
  279. int
  280. cmcpos()
  281. {
  282.   int nscan;            /* # of items successfully scanned in */
  283.                 /* cursor position report */
  284.   int row,col;            /* reported cursor position */
  285.  
  286.   if (console) {
  287.     cputs("\033[6n");        /* device status report: ESC [ 6 n */
  288.     nscan = cscanf("\033[%d;%dR",&row,&col); /* scan response */
  289. #ifndef RAINBOW
  290.     getch();            /* pick up the carriage return */
  291. #endif
  292.     if (nscan != 2)
  293.       return(cmcsb._cmcol);    /* undecipherable response */
  294.     else
  295.       return(col-1);        /* give back response adjusted for 0-origin */
  296.   }
  297.   else
  298.     return(cmcsb._cmcol);    /* unknown for other than console */
  299. }
  300.  
  301. /* cmflush - Flush all pending input on the input source */
  302.  
  303. cmflush(fd)
  304. FILE *fd;
  305. {
  306.   char junk;
  307.  
  308.   if (console)
  309.     while(kbhit())
  310.       getch();
  311.   else
  312.     if (fd != NULL) {
  313.       while (read(fileno(fd),&junk,1) == 1); /* flush other terminal */
  314.     fd->_cnt = 0;
  315.     }
  316. }
  317.  
  318. /* cmtset - Initialize the source terminal.  Check if the source is
  319. ** the console, and if so set the console flag as well as the CM_TTY
  320. ** and CM_CRT flags in the CSB.  Otherwise, clear all three flags.
  321. ** In all cases, the column limit in the CSB is set to 79.
  322. **/
  323.  
  324. #include "xdos.h"            /* for interrupt calls */
  325. #define    CARRY    0x01            /* carry in processor flag register */
  326. #define ISCOT    0x02            /* device status flags */
  327. #define    ISCIN    0x01            
  328. #define    ISDEV    0x80            
  329.  
  330. cmtset()
  331. {
  332.   int ifd;
  333.   int ofd;
  334.   union REGS inregs,outregs;        /* registers for DOS call */
  335.   int flags;                /* processor flags after DOS call */
  336.  
  337.   if (cmcsb._cmij != NULL)
  338.     ifd = fileno(cmcsb._cmij);    /* get desired input source */
  339.   if (cmcsb._cmoj != NULL)
  340.     ofd = fileno(cmcsb._cmoj);
  341.  
  342.   if (cmcsb._cmij != NULL) {
  343.     inregs.h.ah = 0x44;            /* IOCTL call */
  344.     inregs.h.al = 0x00;            /* get device info */
  345.     inregs.x.bx = ifd;            /* file handle */
  346.     flags = intdos(&inregs,&outregs);    /* do the call */
  347. #ifdef LATTICE
  348.     if (((flags & CARRY) != 0) || (outregs.x.ax == 0xff)) /* error? */
  349. #else
  350.     if ((outregs.x.cflag != 0) || (outregs.x.ax == 0xff)) /* error? */
  351. #endif
  352.       console = FALSE;            /* then assume nothing */
  353.     else if ((outregs.x.dx & ISDEV) == 0) /* disk file? */
  354.       console = FALSE;            /* then it's not the console */
  355.     else if (outregs.x.dx & (ISCOT | ISCIN)) /* console input or output? */
  356.       console = TRUE;            /* then set flag */
  357.     else
  358.       console = FALSE;            /* otherwise clear it */
  359.   }
  360.   else {
  361.     console = FALSE;
  362.   }
  363.   if (console)
  364.     cmcsb._cmflg |= (CM_TTY | CM_CRT); /* console is a CRT */
  365.   else
  366.     cmcsb._cmflg &= ~(CM_TTY | CM_CRT); /* anything else is not a tty */
  367.   cmcsb._cmcmx = 79;            /* everything has 80 columns */
  368.   cmcsb._cmrmx = 23;            /* everything has 24 rows */
  369. }
  370.  
  371. /* cmtend - Restore prior terminal state. Nothing needed for PC */
  372.  
  373. cmtend()
  374. {
  375. }
  376.