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

📄 main.c

📁 Linux下VB解释器
💻 C
📖 第 1 页 / 共 4 页
字号:
/*      YABASIC ---  a simple Basic Interpreter    written by Marc-Oliver Ihm 1995-2005    homepage: www.yabasic.de            main.c --- main() and auxilliary functions            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*//* ------------- includes ---------------- */#ifndef YABASIC_INCLUDED#include "yabasic.h"		/* all prototypes and structures */#endif/* ------------- defines ---------------- */#define DONE {current=current->next;break;}	/* reduces type-work */#define COPYRIGHT "Copyright 1995-2005 by Marc-Oliver Ihm"#define BANNER \"\nThis is yabasic version " VERSION ",\nbuilt on "\ARCHITECTURE " at " BUILD_TIME "\n\n      " COPYRIGHT "\n\n"#define BANNER_VERSION \"yabasic " VERSION ", built on " ARCHITECTURE "\n" COPYRIGHT#define YABFORHELP "(type 'yabasic -help' for help)"#define YABMAGIC "__YaBaSiC_MaGiC_CoOkIe__"/* ------------- external references ---------------- */extern int yylineno;		/* current line number */extern int yyparse ();		/* call bison parser *//* ------------- local functions ---------------- */static void std_diag (char *, int, char *);	/* produce standard diagnostic */static void parse_arguments (int, char *argv[]);	/* parse cmd line arguments */static void initialize (void);	/* give correct values to pointers etc ... */static void run_it (void);	/* execute the compiled code */static void end_it (void);	/* perform shutdown operations */#ifdef WINDOWSstatic void chop_command (char *, int *, char ***);	/* chops WIN95-commandline */#endifvoid create_docu_array (void);	/* create array with documentation */int equal (char *, char *, int);	/* helper for processing options */void do_help (char *);		/* process help option */static int mybind (char *);	/* bind a program to the interpreter and save it */char *find_interpreter (char *);	/* find interpreter with full path *//* ------------- global variables ---------------- */struct command *cmdroot;	/* first command */struct command *cmdhead;	/* next command */struct command *lastcmd;	/* last command */struct command *current;	/* currently executed command */int infolevel;			/* controls issuing of error messages */int errorlevel;			/* highest level of error message seen til now */static int debug_count;		/* number of debug messages */static int note_count;		/* number of notes */static int warning_count;	/* number of warning messages */static int error_count;		/* number of error messages */int interactive;		/* true, if commands come from stdin */int is_bound;			/* true, if this executable is bound */static char *to_bind = NULL;	/* name bound program to be written */FILE *bound_program = NULL;	/* points to embedded yabasic program (if any) */char *string;			/* for trash-strings */char *errorstring;		/* for error-strings */int errorcode;			/* error-codes */static int commandcount;	/* total number of commands */int program_state;		/* state of program */char *progname = NULL;		/* name of yabasic-program */int print_docu = FALSE;		/* TRUE, if only docu should be printed */int hold_docu = FALSE;		/* TRUE, if docu should be printed in portions */#ifdef WINDOWSDWORD InitialConsole;		/* initial state of console window */#endifchar *explanation[cLAST_COMMAND - cFIRST_COMMAND + 1];	/* explanations of commands */char *explicit = NULL;		/* yabasic commands given on the command line */char **yabargv;			/* arguments for yabasic */int yabargc;			/* number of arguments in yabargv */static int endreason = erNONE;	/* reason for termination */static int exitcode = 0;static int signal_arrived = 0;/* timing */time_t compilation_start, compilation_end, execution_end;char library_path[200];		/* full path to search libraries */char library_default[200];	/* default full path to search libraries */static struct command *docuhead = NULL;	/* first docu in main */static int docucount = 0;	/* number of docu-lines in array */int check_compat = 0;		/* true, if compatibility should be checked */static char *interpreter_path = NULL;	/* name of interpreter executing; i.e. ARGV[0] */static char *main_file_name = NULL;	/* name of program to be executed *//* ------------- main program ---------------- */intmain (int argc, char **argv){#ifdef WINDOWS  CONSOLE_SCREEN_BUFFER_INFO csbi;  char *lp;  int fromlibpath;#endif  int len;  string = (char *) my_malloc (sizeof (char) * INBUFFLEN);  errorstring = (char *) my_malloc (sizeof (char) * INBUFFLEN);  *errorstring = '\0';  errorcode = 0;  program_state = HATCHED;  infolevel = WARNING;		/* set the initial Infolevel */#ifdef WINDOWS  /* get handle for current thread */  DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),		   GetCurrentProcess (), &mainthread, THREAD_ALL_ACCESS,		   FALSE, 0);  /* get handle of instance */  this_instance = GetModuleHandle (NULL);  /* define my window class */  myclass.style = 0;  myclass.lpfnWndProc = (LPVOID) mywindowproc;  myclass.cbClsExtra = 0;	/* no extra bytes */  myclass.cbWndExtra = 0;  myclass.hInstance = this_instance;  myclass.hIcon = LoadIcon (this_instance, "yabasicIcon");  myclass.hCursor = LoadCursor (NULL, IDC_ARROW);	/*  standard cursor */  myclass.hbrBackground = (HBRUSH) COLOR_WINDOW;	/* default-background */  myclass.lpszMenuName = NULL;  myclass.lpszClassName = my_class;  RegisterClass (&myclass);  /* get console handles */  ConsoleInput = GetStdHandle (STD_INPUT_HANDLE);  ConsoleOutput = GetStdHandle (STD_OUTPUT_HANDLE);  GetConsoleMode (ConsoleInput, &InitialConsole);  /* find out, if launched from commandline */  GetConsoleScreenBufferInfo (ConsoleOutput, &csbi);  Commandline = !((csbi.dwCursorPosition.X == 0)		  && (csbi.dwCursorPosition.Y == 0));  if ((csbi.dwSize.X <= 0) || (csbi.dwSize.Y <= 0))    Commandline = TRUE;#endif  /* get library path */  library_path[0] = '\0';  library_default[0] = '\0';#ifdef UNIX  strcpy (library_default, LIBRARY_PATH);#else  fromlibpath = TRUE;  if (lp = getreg ("librarypath"))    {      strcpy (library_default, lp);      fromlibpath = TRUE;    }  else if (lp = getreg ("path"))    {      strcpy (library_default, lp);      fromlibpath = FALSE;    }  else    {      library_default[0] = '\0';      fromlibpath = FALSE;    }#endif  /* find out, if this executable is bound to a yabasic program */  interpreter_path = find_interpreter (argv[0]);  is_bound = isbound ();  /* parse arguments */  parse_arguments (argc, argv);  /* brush up library path */  if (!library_path[0])    strcpy (library_path, library_default);  len = strlen (library_path);#ifdef UNIX  if (library_path[len - 1] == '/' || library_path[len - 1] == '\\')    library_path[len - 1] = '\0';#else  if (library_path[0])    {      if (library_path[len - 1] != '/' && library_path[len - 1] != '\\')	strcat (library_path, "\\");      if (!fromlibpath)	strcat (library_path, "lib\\");    }#endif  time (&compilation_start);  error (DEBUG, "this is yabasic " VERSION);  initialize ();  program_state = INITIALIZED;  error (NOTE, "calling parser/compiler");  if (interactive)    {      printf ("%s", BANNER);      printf ("Enter your program and type RETURN twice when done.\n\n");      printf	  ("Your program will execute immediately and CANNOT BE SAVED;\n");      printf	  ("create your program with an EXTERNAL EDITOR, if you want to keep it.\n");#ifdef UNIX      printf	  ("Type 'man yabasic' or see the file yabasic.htm for more information,\n");#else      printf	  ("See the documentation within the start-menu for more information,\n");#endif      printf ("or go to www.yabasic.de for online resources.\n\n");    }  program_state = COMPILING;  if (yyparse () && errorlevel > ERROR)    error (ERROR, "Couldn't parse program");  if (errorlevel > ERROR)    create_docu_array ();  add_command (cEND, NULL);  sprintf (string, "read %d line(s) and generated %d command(s)", yylineno,	   commandcount);  error (NOTE, string);  time (&compilation_end);  if (to_bind)    {      if (mybind (to_bind))	{	  sprintf (string, "Successfully bound '%s' and '%s' into '%s'",		   interpreter_path, main_file_name, to_bind);	  error (INFO, string);	  end_it ();	}      else	{	  sprintf (string, "could not bind '%s' and '%s' into '%s'",		   interpreter_path, main_file_name, to_bind);	  error (ERROR, string);	  end_it ();	}    }  if (errorlevel > ERROR && !check_compat)    {      program_state = RUNNING;      run_it ();    }  else    {      program_state = FINISHED;      if (check_compat)	printf	    ("Check for possible compatibility problems done\nProgram will not be executed, %d possible problem(s) reported\n",	     warning_count);      else	error (ERROR, "Program not executed");    }  program_state = FINISHED;  sprintf (string, "%d debug(s), %d note(s), %d warning(s), %d error(s)",	   debug_count, note_count, warning_count, error_count);  error (NOTE, string);  time (&execution_end);  sprintf (string, "compilation time %g second(s), execution %g",	   (double) (compilation_end - compilation_start),	   (double) (execution_end - compilation_end));  error (NOTE, string);  end_it ();  return !(errorlevel > ERROR);}/* ------------- subroutines ---------------- */static voidstd_diag (char *head, int type, char *name)	/* produce standard diagnostic */{  int n, i;  char *s;  struct stackentry *sp;  if (infolevel >= DEBUG)    {      s = string;      if (type > cLAST_COMMAND || type < cFIRST_COMMAND)	{	  sprintf (s, "%s Illegal %d %n", head, type, &n);	}      else	{	  if (name)	    sprintf (s, "%s '%s' (%s) %n", head, explanation[type],		     name ? name : "NULL", &n);	  else	    sprintf (s, "%s '%s' %n", head, explanation[type], &n);	}      s += n;      if (stackhead->prev != stackroot)	{	  sprintf (s, "t[");	  s += 2;	  sp = stackhead;	  for (i = 0; TRUE; i++)	    {	      sp = sp->prev;	      if (sp == stackroot)		break;	      if (i >= 5)		continue;	      if (i > 0)		{		  sprintf (s, ",");		  s++;		}	      switch (sp->type)		{		case stGOTO:		  sprintf (s, "goto%n", &n);		  break;		case stSTRINGARRAYREF:		case stNUMBERARRAYREF:		  if (sp->pointer)		    sprintf (s, "%s()%n", (char *) sp->pointer, &n);		  else		    sprintf (s, "ARRAY()%n", &n);		  break;		case stSTRING:		  sprintf (s, "'%s'%n", (char *) sp->pointer, &n);		  break;		case stNUMBER:		  sprintf (s, "%g%n", sp->value, &n);		  break;		case stLABEL:		  sprintf (s, "label%n", &n);		  break;		case stRETADD:		  sprintf (s, "retadd%n", &n);		  break;		case stRETADDCALL:		  sprintf (s, "retaddcall%n", &n);		  break;		case stSWITCH_MARK:		  sprintf (s, "switch_mark%n", &n);		  break;		case stFREE:		  sprintf (s, "free%n", &n);		  break;		case stROOT:		  sprintf (s, "root%n", &n);		  break;		case stSWITCH_STRING:		  sprintf (s, "switch_string%n", &n);		  break;		case stSWITCH_NUMBER:		  sprintf (s, "switch_number%n", &n);		  break;		default:		  sprintf (s, "unknown%n", &n);		  break;		}	      s += n;	    }	  if (i > 5)	    {	      sprintf (s, ";+%d%n", i - 5, &n);	      s += n;	    }	  strcat (s, "]b");	}      error (DEBUG, string);    }}struct command *add_command (int type, char *name)     /* get room for new command, and make a link from old one */{  struct command *new;  if (infolevel >= DEBUG)    std_diag ("creating", type, name);  cmdhead->type = type;		/* store command */  cmdhead->line = yylineno;  cmdhead->lib = currlib;  cmdhead->cnt = commandcount;  if (!name || !*name)    cmdhead->name = NULL;  else    cmdhead->name = my_strdup (name);  commandcount++;  cmdhead->pointer = NULL;	/* no data yet */  cmdhead->jump = NULL;  cmdhead->nextassoc = NULL;  cmdhead->switch_id = get_switch_id ();  if (!currlib->datapointer && cmdhead->type == cDATA)    currlib->firstdata = currlib->datapointer = cmdhead;  /* link into chain of commands referencing a symbol */  if (name)    {      if (lastref)	lastref->nextref = cmdhead;      lastref = cmdhead;    }  /* create new command */  new = (struct command *) my_malloc (sizeof (struct command));  /* and initialize */  new->next = NULL;  new->prev = cmdhead;  new->pointer = NULL;  new->symbol = NULL;  new->nextref = NULL;  new->nextassoc = NULL;  new->name = NULL;  cmdhead->next = new;  lastcmd = cmdhead;  cmdhead = cmdhead->next;  return lastcmd;}static voidparse_arguments (int cargc, char *cargv[])     /* parse arguments from the command line */{  char **argv;  int argc, larg;#ifdef UNIX  char *parg;  int i;#endif  int ar;  FILE *inputfile = NULL;  char *option;  char *info;  int options_done = FALSE;  if (cargc > 1)    larg = strlen (cargv[1]);  else    larg = 0;#ifdef UNIX  if (cargc > 0)    {      /* get room for arguments */      argv = (char **) my_malloc ((larg + cargc + 1) * sizeof (char *));      /* copy zero argument */      argv[0] = cargv[0];      argc = 0;      /* chop first argument into pieces */      if (cargc >= 2)	{	  parg = strtok (my_strdup (cargv[1]), " \t");	  for (argc = 1; parg; argc++)	    {	      argv[argc] = parg;	      parg = strtok (NULL, " \t");	    }	}      /* copy other arguments */      for (i = 2; i < cargc; i++)	{	  argv[argc] = cargv[i];	  argc++;	}    }  else    {      argv = cargv;      argc = cargc;    }#else  argv = cargv;  argc = cargc;#endif  yabargv = (char **) my_malloc ((larg + cargc + 1) * sizeof (char *));  yabargc = 0;  if (is_bound)    options_done = 1;  /* process options */  for (ar = 1; ar < argc; ar++)    {      option = argv[ar];      if (!options_done)	{	  if (equal ("-help", option, -2) ||	      equal ("-?", option, 2) ||	      equal ("-version", option, 2) ||	      equal ("-licence", option, 4) ||	      equal ("-license", option, 4))	    {	      do_help (option);	      end_it ();	    }	  else if (equal ("-check", option, 2))	    {	      check_compat = 1;	    }	  else if (!strcmp ("--", option))	    {	      options_done = TRUE;	      continue;	    }	  else if (equal ("-infolevel", option, 2))	    {	      ar++;	      if (ar >= argc)		{		  error (ERROR, "no infolevel specified " YABFORHELP);		  end_it ();		}	      info = argv[ar];	      if (!strncmp (info, "debug", strlen (info)))		infolevel = DEBUG;	      else if (!strncmp (info, "note", strlen (info)))		infolevel = NOTE;	      else if (!strncmp (info, "warning", strlen (info)))		infolevel = WARNING;	      else if (!strncmp (info, "error", strlen (info)))		infolevel = ERROR;	      else if (!strncmp (info, "fatal", strlen (info)))		infolevel = FATAL;	      else if (!strncmp (info, "bison", strlen (info)))		{		  yydebug = 1;		  infolevel = DEBUG;		}	      else		{		  sprintf (string, "there's no infolevel '%s' " YABFORHELP,			   argv[ar]);		  error (ERROR, string);		  end_it ();		}	    }	  else if (equal ("-fg", option, 3)		   || equal ("-foreground", option, 4))	    {	      ar++;	      if (ar >= argc)		{		  error (ERROR,			 "no foreground colour specified " YABFORHELP);		  end_it ();		}	      foreground = my_strdup (argv[ar]);	    }	  else if (equal ("-bg", option, 2)		   || equal ("-background", option, 2))	    {	      ar++;	      if (ar >= argc)		{		  error (ERROR,			 "no background colour specified (-h for help)");		  end_it ();		}	      background = my_strdup (argv[ar]);	    }	  else if (equal ("-geometry", option, 2))	    {	      ar++;	      if (ar >= argc)		{		  error (ERROR,			 "no geometry string specified (-h for help)");		  end_it ();		}	      geometry = my_strdup (argv[ar]);	    }	  else if (equal ("-bind", option, 3))	    {	      ar++;	      if (ar >= argc)		{		  error (ERROR,			 "name of bound program to be written is missing");		  end_it ();		}	      to_bind = my_strdup (argv[ar]);	    }	  else if (equal ("-execute", option, 2))	    {	      ar++;

⌨️ 快捷键说明

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