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

📄 io.c

📁 Linux下VB解释器
💻 C
📖 第 1 页 / 共 3 页
字号:
/*      YABASIC ---  a simple Basic Interpreter    written by Marc-Oliver Ihm 1995-2005    homepage: www.yabasic.de        io.c --- code for screen and file i/o        This file is part of yabasic and  may be copied only     under the terms of either the Artistic License or     the GNU General Public License (GPL), both of which     can be found at www.yabasic.de*//* ------------- defines ---------------- */#ifdef WINDOWS#define WM_WANTKEY (WM_APP+7)#endif/* ------------- includes ---------------- */#ifndef YABASIC_INCLUDED#include "yabasic.h"		/* all prototypes and structures */#endif/* ------------- local defines ----------------- */#define YC_BLACK 0#define YC_WHITE 1#define YC_RED 2#define YC_BLUE 3#define YC_GREEN 4#define YC_YELLOW 5#define YC_CYAN 6#define YC_MAGENTA 7#ifndef COLOR_BLACK#define COLOR_BLACK	0#define COLOR_RED	1#define COLOR_GREEN	2#define COLOR_YELLOW	3#define COLOR_BLUE	4#define COLOR_MAGENTA	5#define COLOR_CYAN	6#define COLOR_WHITE	7#endif#ifndef A_COLOR#define A_COLOR 0xff00#endif/* ------------- external references ---------------- */extern int yylineno;		/* current line number */extern int yyparse ();		/* call bison parser *//* ------------- local functions ---------------- */static int onechar (void);	/* read one char from currentinstream */static void backchar (int);	/* put char back into stream */static void readline (void);	/* read one line from current stream */static void curinit (void);	/* initialize curses */static void initcol (void);	/* initialize curses colors */int checkstream (void);		/* test if currst is still valid */#ifdef WINDOWSstatic DWORD keythread (LPWORD);	/* wait for key input from console */static int is_valid_key (INPUT_RECORD *);	/* check if input rec is valid key */#endifint name2yc (char *);		/* convert a color name to an integer */int yc2oc (int, int);		/* convert a yabasic color to operating system color */char *yc2short (int);		/* convert yabasic colours to short colour name */#ifdef UNIXint oc2yc (int);		/* convert an operating system color to yabasic color */#endif/* ------------- global variables ---------------- */static int prompted;		/* TRUE, if prompt is fresh */int read_controls;		/* TRUE, if input should read control characters */FILE *streams[FOPEN_MAX];	/* file streams */int stream_modes[FOPEN_MAX];	/* modes for streams */int lprstream = -1;		/* stream associated with lineprinter */static int currstr = STDIO_STREAM;	/* currently switched stream */static FILE *cinstr;		/* current stream for input */static FILE *coutstr;		/* current stream for output */static char linebuffer[INBUFFLEN];	/* buffer for one line of input */int curinized = FALSE;		/* true, if curses has been initialized */static char *currchar;		/* current char to read */static short stdfc;		/* standard foreground color of window */static short stdbc;		/* standard background color of window */#ifdef UNIXint winpid = -1;		/* pid of process waiting for window keys */int termpid = -1;		/* pid of process waiting for terminal keys */FILE *lineprinter = NULL;	/* handle for line printer */#elseHANDLE wantkey = INVALID_HANDLE_VALUE;	/* mutex to signal key desire */HANDLE gotkey = INVALID_HANDLE_VALUE;	/* mutex to signal key reception */HANDLE wthandle = INVALID_HANDLE_VALUE;	/* handle of win thread */HANDLE kthandle = INVALID_HANDLE_VALUE;	/* handle of inkey thread */DWORD ktid;			/* id of inkey thread */int LINES = 0;			/* number of lines on screen */int COLS = 0;			/* number of columns on screen */HANDLE ConsoleInput;		/* handle for console input */HANDLE ConsoleOutput;		/* handle for console output */HANDLE lineprinter = INVALID_HANDLE_VALUE;	/* handle for line printer */#endif/* ------------- functions ---------------- */voidcreate_print (char type)	/* create command 'print' */{  struct command *cmd;  cmd = add_command (cPRINT, NULL);  cmd->pointer = my_malloc (sizeof (int));  /* store type of print  */  cmd->tag = type;}voidprint (struct command *cmd)	/* print on screen */{  int type;  struct stackentry *p, *q, *r;  static int last = 'n';  char *s;  int x, y;  long int n;  double d;#ifdef WINDOWS  CONSOLE_SCREEN_BUFFER_INFO csbi;  SMALL_RECT screen;  COORD to;  CHAR_INFO ci;#endif  r = NULL;  type = cmd->tag;  if (!checkstream ())    return;  switch (type)    {    case 'n':			/* print newline */      if (curinized && coutstr == stdout)	{#ifdef WINDOWS	  GetConsoleScreenBufferInfo (ConsoleOutput, &csbi);	  x = csbi.dwCursorPosition.X;	  y = csbi.dwCursorPosition.Y;	  if (y >= LINES - 1)	    {	      screen.Left = 0;	      screen.Right = COLS;	      screen.Top = 1;	      screen.Bottom = LINES;	      to.X = 0;	      to.Y = 0;	      ci.Char.AsciiChar = ' ';	      ci.Attributes =		  FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;	      ScrollConsoleScreenBuffer (ConsoleOutput, &screen, NULL, to,					 &ci);	      to.X = 0;	      to.Y = y;	    }	  else	    {	      to.X = 0;	      to.Y = y + 1;	    }	  SetConsoleCursorPosition (ConsoleOutput, to);	  break;#else	  getyx (stdscr, y, x);	  if (y >= LINES - 1)	    {	      scrl (1);	      y = y - 1;	    }	  move (y + 1, 0);	  refresh ();	  break;#endif	}      else	{	  string[0] = '\n';	  if (abs (currstr) == lprstream)	    {	      string[1] = '\r';	      string[2] = '\0';	    }	  else	    {	      string[1] = '\0';	    }	}      onestring (string);      break;    case 't':			/* print tab */      string[0] = '\t';      string[1] = '\0';      onestring (string);      break;    case 'd':			/* print double value */      p = pop (stNUMBER);      d = p->value;      n = (int) d;      if (n == d && d <= LONG_MAX && d >= LONG_MIN)	sprintf (string, "%s%ld", (last == 'd') ? " " : "", n);      else	sprintf (string, "%s%g", (last == 'd') ? " " : "", d);      onestring (string);      break;    case 'U':      r = pop (stSTRING);    case 'u':			/* print using */      p = pop (stSTRING);      q = pop (stNUMBER);      type = 'd';      s = string;      if (last == 'd')	{	  *s = ' ';	  s++;	}      if (!myformat (s, q->value, p->pointer, r ? r->pointer : NULL))	{	  sprintf (string, "'%s' is not a valid format",		   (char *) p->pointer);	  error (ERROR, string);	  break;	}      onestring (string);      break;    case 's':      p = pop (stSTRING);      onestring ((char *) p->pointer);      break;    }  last = type;}voidmymove ()			/* move to specific position on screen */{  int x, y;#ifdef WINDOWS  COORD coord;#endif  y = (int) pop (stNUMBER)->value;  if (y < 0)    y = 0;  if (y > LINES - 1)    y = LINES - 1;  x = (int) pop (stNUMBER)->value;  if (x < 0)    x = 0;  if (x > COLS - 1)    x = COLS - 1;  if (!curinized)    {      error (ERROR, "need to call 'clear screen' first");      return;    }#ifdef UNIX  move (y, x);  refresh ();#else  coord.X = x;  coord.Y = y;  SetConsoleCursorPosition (ConsoleOutput, coord);#endif}voidclearscreen ()			/* clear entire screen */{#ifdef WINDOWS  DWORD written;		/* number of chars actually written */  COORD coord;			/* coordinates to start writing */#endif  if (!curinized)    curinit ();#ifdef UNIX  clear ();  refresh ();#else  coord.X = 0;  coord.Y = 0;  FillConsoleOutputCharacter (ConsoleOutput, ' ', LINES * COLS, coord,			      &written);  FillConsoleOutputAttribute (ConsoleOutput,			      FOREGROUND_RED | FOREGROUND_GREEN |			      FOREGROUND_BLUE, LINES * COLS, coord,			      &written);  SetConsoleCursorPosition (ConsoleOutput, coord);#endif}static voidcurinit (void)			/* initialize curses */{#ifdef WINDOWS  CONSOLE_SCREEN_BUFFER_INFO coninfo;	/* receives console size */#endif#ifdef UNIX  initscr ();  initcol ();  setscrreg (0, LINES);  scrollok (stdscr, TRUE);  leaveok (stdscr, TRUE);  keypad (stdscr, TRUE);  intrflush (stdscr, FALSE);  curs_set (0);  def_prog_mode ();#else  GetConsoleScreenBufferInfo (ConsoleOutput, &coninfo);  COLS = coninfo.srWindow.Right + 1;  LINES = coninfo.srWindow.Bottom + 1;  initcol ();#endif  curinized = TRUE;}char *inkey (double maxtime)		/* get char from keyboard */{  char *skey;#ifdef WINDOWS  int ms;			/* number of milliseconds to wait */  DWORD oflags;			/* saves normal state of console input buffer */  DWORD flags;			/* new input mode for console input buffer */  static char conkeybuff[100], winkeybuff[100];#else  fd_set readfds;  struct timeval tv;  int maxfd;  int winfd[2], termfd[2];  char retkey[100];  int status, ret;#endif  if (maxtime >= 0.0 && maxtime < 0.01)    maxtime = 0.01;  if (!curinized)    {      error (ERROR, "need to call 'clear screen' first");      return my_strdup ("");    }#ifdef UNIX  retkey[0] = '\0';  winfd[0] = winfd[1] = termfd[0] = termfd[1] = -1;  winpid = termpid = -1;  if (pipe (winfd) || pipe (termfd))    {      error (ERROR, "Couldn't open pipes");      goto sane_state;    }  winpid = fork ();  if (winpid == 0)    {      /* this is the child */      signal (SIGINT, SIG_DFL);      signal (SIGFPE, SIG_DFL);      signal (SIGSEGV, SIG_DFL);      retkey[0] = '\0';      if (winopened)	getwinkey (retkey);      if (*retkey)	write (winfd[1], retkey, strlen (retkey));      wait (&status);      exit (0);    }  else if (winpid == -1)    {      error (ERROR, "couldn't fork child");      goto sane_state;    }  termpid = fork ();  if (termpid == 0)    {      /* this is the child */      signal (SIGINT, SIG_DFL);      signal (SIGFPE, SIG_DFL);      signal (SIGSEGV, SIG_DFL);      retkey[0] = '\0';      noecho ();      cbreak ();      timeout (-1);      gettermkey (retkey);      if (*retkey)	write (termfd[1], retkey, strlen (retkey));      wait (&status);      exit (0);    }  else if (termpid == -1)    {      error (ERROR, "Couldn't fork child");      goto sane_state;    }  FD_ZERO (&readfds);  FD_SET (termfd[0], &readfds);  FD_SET (winfd[0], &readfds);  fflush (stdout);  maxfd = (termfd[0] > winfd[0]) ? termfd[0] : winfd[0];  if (maxtime >= 0)    {      tv.tv_sec = (int) maxtime;      tv.tv_usec = (maxtime - (int) maxtime) * 1000000.;      ret = select (maxfd + 1, &readfds, NULL, NULL, &tv);    }  else    {      ret = select (maxfd + 1, &readfds, NULL, NULL, NULL);    }  if (ret == -1)    {      error (ERROR, "select failed");      goto sane_state;    }  if (FD_ISSET (termfd[0], &readfds))    {      ret = read (termfd[0], retkey, 100);    }  else if (FD_ISSET (winfd[0], &readfds))    {      ret = read (winfd[0], retkey, 100);      if (!strncmp ("MB", retkey, 2))	getmousexybm (retkey, &mousex, &mousey, &mouseb, &mousemod);    }  else    ret = 0;  retkey[ret] = '\0';sane_state:  skey = retkey;  if (winfd[0] > 0)    close (winfd[0]);  if (winfd[1] > 0)    close (winfd[1]);  if (termfd[0] > 0)    close (termfd[0]);  if (termfd[1] > 0)    close (termfd[1]);  if (termpid > 0)    {      kill (termpid, SIGTERM);      waitpid (termpid, &status, 0);      termpid = -1;    }  if (winpid > 0)    {      kill (winpid, SIGTERM);      waitpid (winpid, &status, 0);      winpid = -1;    }  reset_prog_mode ();		/* prepare for input afterwards */#elif WINDOWS  /* create event to signal key */  if (gotkey == INVALID_HANDLE_VALUE)    gotkey = CreateEvent (NULL, FALSE, FALSE, NULL);  if (wantkey == INVALID_HANDLE_VALUE)    wantkey = CreateEvent (NULL, TRUE, FALSE, NULL);  conkeybuff[0] = winkeybuff[0] = '\0';  GetConsoleMode (ConsoleInput, &oflags);  flags = oflags & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);  SetConsoleMode (ConsoleInput, flags);  /* create thread to observe console */  if (kthandle == INVALID_HANDLE_VALUE)    {      kthandle = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) keythread,			       (LPVOID) conkeybuff, 0, (LPDWORD) & ktid);    }  /* signal, that we want a key */  if (winopened)    {      SendMessage (window, WM_WANTKEY, 0, (LPARAM) winkeybuff);    }  SetEvent (wantkey);  ms = (int) (1000 * maxtime);  if (ms < 0)    WaitForSingleObject (gotkey, INFINITE);  else    WaitForSingleObject (gotkey, ms);  ResetEvent (wantkey);  SetConsoleMode (ConsoleInput, oflags);  if (*winkeybuff)    skey = winkeybuff;  else    skey = conkeybuff;#endif  return my_strdup (skey);}#ifdef WINDOWSstatic DWORDkeythread (LPWORD lparam)	/* wait for key input from console */{  INPUT_RECORD inrec;		/* for reading key-event */  int key, skey;  int num;  char *keybuff;  HANDLE evn[2];  keybuff = (char *) lparam;  keybuff[0] = '\0';  evn[0] = wantkey;  evn[1] = ConsoleInput;  do    {      do	{	  do	    {	      WaitForMultipleObjects (2, evn, TRUE, INFINITE);	      ReadConsoleInput (ConsoleInput, &inrec, 1, &num);	    }	  while (!is_valid_key (&inrec));	  if (isprint (inrec.Event.KeyEvent.uChar.AsciiChar))	    {	      keybuff[0] = inrec.Event.KeyEvent.uChar.AsciiChar;	      keybuff[1] = '\0';	    }	  else	    {	      key = inrec.Event.KeyEvent.wVirtualKeyCode;	      skey = -1;	      switch (key)		{		case 0x1b:		  skey = kESC;		  break;		case 0x0d:		  skey = kENTER;		  break;		case 0x09:		  skey = kTAB;		  break;		case 0x21:		  skey = kSCRNUP;		  break;		case 0x22:		  skey = kSCRNDOWN;		  break;		case 0x70:		  skey = kF1;		  break;		case 0x71:		  skey = kF2;		  break;		case 0x72:		  skey = kF3;		  break;		case 0x73:		  skey = kF4;		  break;		case 0x74:		  skey = kF5;		  break;		case 0x75:		  skey = kF6;		  break;		case 0x76:		  skey = kF7;		  break;		case 0x77:		  skey = kF8;		  break;		case 0x78:		  skey = kF9;		  break;		case 0x79:		  skey = kF10;		  break;		case 0x7a:		  skey = kF11;		  break;		case 0x7b:		  skey = kF12;		  break;		case 0x24:		  skey = kHOME;		  break;		case 0x23:		  skey = kEND;		  break;		case 0x2d:		  skey = kINS;		  break;		case 0x2e:		  skey = kDEL;		  break;		case 0x08:		  skey = kBACKSPACE;		  break;		case 0x27:		  skey = kRIGHT;		  break;		case 0x25:		  skey = kLEFT;		  break;		case 0x28:		  skey = kDOWN;		  break;		case 0x26:		  skey = kUP;		  break;		default:		  sprintf (keybuff, "key%x", key);		}	      if (skey > 0)		strcpy (keybuff, ykey[skey]);	    }	  if (!keybuff[0])	    printf ("Loop !\n");	}      while (!keybuff[0]);      ResetEvent (wantkey);      SetEvent (gotkey);    }  while (TRUE);  return 0;}static intis_valid_key (INPUT_RECORD * rec)	/* check if input rec contains valid key */{  if (rec->EventType != KEY_EVENT ||      !rec->Event.KeyEvent.bKeyDown ||      rec->Event.KeyEvent.wVirtualKeyCode == VK_SHIFT ||

⌨️ 快捷键说明

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