⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winio.c

📁 一个c语言写做的编译器的源码
💻 C
字号:
/*@A (C) 1992 Allen I. Holub                                                */
#include "cur.h"

#if ( (0 BCC(+1)) || (0 MSC(+1)) )	/* Microsoft or Borland Compilers */
#include <dos.h>			/* Prototype for bdos().	  */
#endif

/*--------------------------------------------------------
 * WINIO.C	Lowest level I/O routines:
 * 	waddch(win,c)  		wgetch(win)
 *	echo()			noecho()
 *	nl()			nonl()
 *	crmode()		nocrmode()
 *--------------------------------------------------------
 */

PRIVATE int Echo   = 1;		/* Echo enabled			  */
PRIVATE int Crmode = 0;		/* If 1, use buffered input	  */
PRIVATE int Nl	   = 1;		/* If 1, map \r to \n on input	  */
				/* and map both to \n\r on output */
void echo	() {  Echo = 1; }
void noecho	() {  Echo = 0; }
void nl		() {  Nl   = 1; }
void nonl	() {  Nl   = 0; }

void crmode()
{
      /* setvbuf(stdin, NULL, _IONBF, 0);  /* Turn off buffering */
    Crmode = 1;
}

void nocrmode()
{
     /* freopen( "/dev/con", "r", stdin ); */
    Crmode = 0;
}

/*--------------------------------------------------------*/

static  char	*getbuf(win, buf)
WINDOW	*win;
char	*buf;
{
    /* Get a buffer interactively. ^H is a destructive backspace. This routine
     * is mildly recursive (it's called from wgetch() when Crmode is false.
     * The newline is put into the buffer. Returns it's second argument.
     */

    int  c;
    char *sbuf = buf;

    Crmode = 1;
    while( (c = wgetch(win)) != '\n' && c != '\r' )
    {
	switch( c )
	{
	case '\b':  if( buf > sbuf )
	            {
			--buf;
			wprintw( win, " \b" );
		    }
		    else
		    {
			wprintw( win, " " );
			putchar('\007');
		    }
		    break;

	default:    *buf++ = c;
		    break;
	}
    }
    *buf++ = c   ;	/* Add line terminator (\n or \r) */
    *buf   = '\0';
    Crmode = 0   ;
    return sbuf  ;
}

/*--------------------------------------------------------*/

int	wgetch( win )
WINDOW	*win;
{
    /* Get a character from DOS without echoing. We need to do this in order
     * to support (echo/noecho). We'll also do noncrmode input buffering here.
     * Maximum input line length is 132 columns.
     *
     * In nocrmode(), DOS functions are used to get a line and all the normal
     * command-line editing functions are available. Since there's no way to
     * turn off echo in this case, characters are echoed to the screen
     * regardless of the status of echo(). In order to retain control of the
     * window, input fetched for wgetch() is always done in crmode, even if
     * Crmode isn't set. If nl() mode is enabled, carriage return (Enter, ^M)
     * and linefeed (^J) are both mapped to '\n', otherwise they are not mapped.
     *
     * Characters are returned in an int. The high byte is 0 for normal
     * characters. Extended characters (like the function keys) are returned
     * with the high byte set to 0xff and the character code in the low byte.
     * Extended characters are not echoed.
     */

    static unsigned char  buf[ 133 ];	/* Assuming initialization to 0's */
    static unsigned char  *p = buf;
    register	    int	  c;

    if( !Crmode )
    {
	if( !*p )
	    p = getbuf( win, buf );
	return( Nl && *p == '\r' ) ? '\n' : *p++ ;
    }
    else
    {
	if( (c = bdos(8,0,0) & 0xff) == ('Z'-'@') )	/* Ctrl-Z */
		return EOF ;
	else if( !c )					/* Extended char */
		c = ~0xff | bdos(8,0,0) ;
	else
	{
	    if( c == '\r' &&  Nl )
		c = '\n' ;

	    if( Echo )
		waddch( win, c );
	}
	return c;
    }
}

/*--------------------------------------------------------*/

int	waddch( win, c )
WINDOW	*win;
int	c;
{
    /*	Print a character to an active (not hidden) window:
     *	The following are handled specially:
     *
     *	\n  Clear the line from the current cursor position  to the right edge
     *	    of the window. Then:
     *	        if nl() is active:
     *		    go to the left edge of the next line
     *	        else
     *		    go to the current column on the next line
     *	    In addition, if scrolling is enabled, the window scrolls if you're
     *	    on the bottom line.
     *	\t  is expanded into an 8-space field. If the tab goes past the right
     *      edge of the window, the cursor wraps to the next line.
     *	\r  gets you to the beginning of the current line.
     *	\b  backs up one space but may not back up past the left edge of the
     *      window. Nondestructive. The curses documentation doesn't say that
     *      \b is handled explicitly but it does indeed work.
     *	ESC This is not standard curses but is useful. It is valid only if
     *      DOESC was true during the compile. All characters between an ASCII
     *	    ESC and an alphabetic character are sent to the output but are other
     *      wise ignored. This let's you send escape sequences directly to the
     *      terminal if you like. I'm assuming here that you won't change
     *      windows in the middle of an escape sequence.
     *
     * Return ERR if the character would have caused the window to scroll
     * illegally, or if you attempt to write to a hidden window.
     */

#ifdef DOESC
    static  int	    saw_esc = 0;
#endif
    int		    rval    = OK;

    if( win->hidden )
	return ERR;

    cmove(win->y_org + win->row, win->x_org + win->col);

#ifdef DOESC
    if( saw_esc )
    {
	if( isalpha( c ) )
	    saw_esc = 0;
	outc(c, win->attrib );
    }
    else
#endif
    {
	switch( c )
	{
#ifdef DOESC
	case '\033': if( saw_esc )
			saw_esc = 0;
		     else
		     {
			saw_esc = 1;
			outc('\033', win->attrib );
		     }
		     break;
#endif
	case '\b':  if( win->col > 0 )
		    {
		        outc( '\b', win->attrib  );
		        --( win->col );
		    }
		    break;

	case '\t':  do {
			waddch( win, ' ' );
		    } while( win->col % 8 );
		    break;

	case '\r':  win->col = 0;
		    cmove(win->y_org + win->row, win->x_org);
		    break;

	default:    if( (win->col + 1) < win->x_size )
		    {
			/* If you're not at the right edge of the window, */
			/* print the character and advance.		  */

			++win->col;
			outc(c, win->attrib );
			break;
		    }
		    replace(c);	  	  /* At right edge, don't advance */
		    if( !win->wrap_ok )
			break;

		    /* otherwise wrap around by falling through to newline */

	case '\n':  if( c == '\n' )	   /* Don't erase character at far */
			wclrtoeol( win );  /* right of the screen.	   */

		    if( Nl )
			win->col = 0;

		    if( ++(win->row) >= win->y_size )
		    {
			rval = wscroll( win, 1 );
			--( win->row );
		    }
		    cmove( win->y_org + win->row, win->x_org + win->col);
		    break;
	}
    }
    return rval;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -