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

📄 main.cpp

📁 UC Library Extensions UnderC comes with a pocket implementation of the standard C++ libraries, wh
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  else
  // *add 1.2.1 Interactive Help
  if (ppd == "help") show_help("help.txt",Input::next_token(true),'#');
  else
  if (ppd == "li") Function::lookup(Input::next_token(true))->line_nos()->dump(cmsg);
    // *fix 1.2.1 (Eric) Complain if this command is not recognized
  else 
     cerr << '\'' << ppd << "\' is not a command or preprocessor statement" << endl;
  return true;
}

/*static*/ int mInteractiveMode = 1;
static string mUCDir;
static char* mPgmName;

bool interactive_mode()  { return mInteractiveMode; }
string uc_home_dir()     { return mUCDir; }

void bail_out()
{
  check_error();
  exit(-1);
}

int setup_lib()
{
 Parser::init_lib();
 return 0;
}

char *uc_get_title()
{ return mUCTitle; }

void Main::initialize()
{
  Exception::initialize();
  Keywords::init();
  Parser::init();
  Operators::init();
  Expressions::init();
  UCTokenStream::init();
#ifdef _WCON
  IDE::initialize();
 // Non-Interactive
  mInteractiveMode = true;
#endif
}

#ifdef _DEBUG
void init_mem_check() // *DEBUG*
{
    static bool init = false;
    if (! init) { 
        init = true;
// *DEBUG* Fine control of leak detection
// Get current flag
     int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );

// Turn on leak-checking bit
  //  tmpFlag |= _CRTDBG_LEAK_CHECK_DF;

// Turn on check-always bit
     tmpFlag |= _CRTDBG_CHECK_ALWAYS_DF;

     tmpFlag |= _CRTDBG_DELAY_FREE_MEM_DF;

// Turn off CRT block checking bit
//   tmpFlag &= ~_CRTDBG_CHECK_CRT_DF;

// Set flag to the new value
    _CrtSetDbgFlag( tmpFlag );
    }
}


int check_mem() //  *DEBUG*
{
  init_mem_check();
  return _CrtCheckMemory();
}
#endif

// *add 1.1.2 Please note that this does NOT work under Linux!
char *Main::uc_exec_name()
{
  return mPgmName;
}

string Main::uc_lib_dir()
{
  return uc_home_dir() + "/lib/";
}

bool add_include_path(string path)
{
  Utils::check_path_end(path);
  if (! Utils::can_access(path)) {
     error("Cannot find include directory " + path);
	 return false;
  }
  TokenStream::set_include_dir(path.c_str());
  return true;
}

bool extract_options(int *argc, char **argv, char *opt, char **optstring)
{
  char *p = argv[1];
  if (p && p[0]=='-') {
     *opt = p[1];
     *optstring = p+2;
	 for (int i = 1; i < *argc; i++) argv[i] = argv[i+1];
	 --(*argc);
	 return true;
  } else return false;
}

// *add 1.2.2 -D adds a preprocessor macro, in the usual way (there must be NO space before the NAME=SUBST)
bool add_prepro_macro(char *str)
{
  char *name = strtok(str," =");
  if (! name) return false;
  char *subst = strtok(NULL," =");
  TokenStream::macro_subst(name,subst ? subst : "");
  return true;
}

// *add 1.1.4 The -I option will add another include path....
// *add 1.1.4
//  Environment var UC_DEFAULT_ARGS can contain extra stuff
//  which will be appended to the commmand line passed to UC
// *fix 1.1.4W File names on the WCON command line can now contain spaces
// *change 1.2.0 -O switches off over-allocation
//  Pointer check is no longer on by default in release build; use -P.
//  -W suppresses dynamic link warnings; it now switches off verbose import information as well.


bool Main::process_command_line(int& argc, char**& argv)
{
  char *paths[MAX_INCLUDE_PATHS];
  int ipaths = 0;
  bool force_interactive = false;
  char *inc_path = NULL;
  bool use_gtk = false;
  char *extra_args = getenv("UC_DEFAULT_ARGS");
  Utils::Args args(argc,argv);
  args.set_stop_after_file();

  if (extra_args && argv) {
    argv = args.append_extra_args(extra_args);
  }

  special_init(&argc,&argv,use_gtk);

  // under Win32, we try to deduce where we're called from using argv[0]
#ifdef _WIN32
  if (argv != NULL) {
    char *progname = argv[0];
    mPgmName = strdup(progname);
    Utils::strip_last(progname);  // strip off the '\ucw.exe'
#ifdef _DEBUG
    Utils::strip_last(progname);   // strip off the 'wdebug' 
    Utils::strip_last(progname);   // strip off the 'src'
#endif         
    mUCDir = argv[0];
   }
#endif

   // UC_HOME is determined by evaluating all of the following. The
   // last one that is set is used as the final value.
   //
   //  - the compiled in default
   //    (under Win32 we get this from argv[0])
   //  - the UC_HOME environment variable
   //  - the -H option
   
   // *fix 1.2.8 don't use the UC_HOME macro under Win32; rely on argv[0]
   // for the initial guess.

#if defined(UC_HOME) && ! defined(_WIN32)
    inc_path = UC_HOME;
#else
  // *fix 1.2.9 argv==NULL when this routine is called in the DLL version!
    if (argv) mUCDir = argv[0];
#endif

  char *t;
  if (t=getenv("UC_HOME")) {
    // the value set in the environment overrides the compiled in default
    inc_path = t;  // *fix 1.0.0L bash doesn't like 'UC-INC'
  }
  string path;  
  if (inc_path==NULL) {
#ifdef WIN32    
   path = mUCDir;
#endif
  } else { 
    path = inc_path;
    mUCDir = inc_path; // *fix 1.0.0L UC_HOME must override this!
  }
 
  if (argv != NULL) {
    char opt;
    while (args.get_opt(&opt)) {
      switch(opt) {
      // the command line option overrides any previously set value	
      case 'H': path = mUCDir = args.get_opt_parameter(); break;  // *add 1.1.3 Can override UC_HOME
      case 'I': 
          if (ipaths == MAX_INCLUDE_PATHS) error("Exceeded available include paths");
          else paths[ipaths++] = args.get_opt_parameter();
          break;
      case 'G': use_gtk = true; break;
      case 'O': Parser::debug.do_overalloc ^= 1; break;
      case 'P': Parser::debug.ptr_check = true; break;
      case 'W': Parser::debug.suppress_link_errors = true; break;
      case 'D': add_prepro_macro(args.get_opt_parameter()); break;
      case 'i': force_interactive = true; break;
      case 'F': Parser::debug.attempt_inline = true; break;  // *add 1.2.3a New Optimization flag
// *add 1.2.5 run in specified directory
      case 'r': Utils::change_dir(args.get_opt_parameter()); break;
// *add 1.2.5 switch on range checking of arrays and vectors          
      case 'R': Parser::debug.range_check = true;            break;
// *add 1.2.6 Outputing version and help
//* #ifdef _CONSOLE
      case 'v': cout << "UnderC " << mUCVersion << endl; return false;
      case '-': 
         if (strcmp(args.get_opt_parameter(),"help")==0)
         {
             show_help("cmd-help.txt",NULL,'-');
             return false;
         }
      break;
      // *add 1.2.9 Evaluating expressions from the command-line
      case 'e':
          uc_eval(args.get_opt_parameter(),true,true);
          exit(0);
          break;
//* #endif
// *add 1.2.6 These are also available as #opt parameters
      case 'T': Parser::debug.use_typedef_names = true;     break;
      case 'S': Parser::debug.skip_method_bodies = false; break; 
      default: cerr << "unrecognized option: " << opt << endl; return false;
      }
    }
    if (Parser::debug.range_check) add_builtin_macro("_RANGE_CHECK");
  }

// *change 1.2.2b The Windows GUI build is _always_ interactive, and the console
// build is interactive if (a) there are no args or (b) forced with the -i option.
#ifdef _WCON
  mInteractiveMode = force_interactive || argc == 1; // true;
#else
  mInteractiveMode = force_interactive || argc == 1;
#endif

 Utils::check_path_end(path);
 path += "include";
 if (! add_include_path(path)) return false;

// NOW we may add the extra paths, if any
 for(int i = 0; i < ipaths; i++)
	  add_include_path(paths[i]);

 return true;
}

void Main::banner()
{
#ifdef _WCON
    wcon_set_size(20,50,600,500);
    wcon_set_title(mUCTitle);
    wcon_prompt_char(';',0);
#endif
    cmsg << "UnderC C++ Interpreter vs " << mUCVersion << endl;
    cmsg << "Steve Donovan, 2001-2003" << endl;
    cmsg << "This program is GPL'd; see LICENCE for details" << endl;
}

void Main::finalize()
{
// *add 1.2.3 Destroy any statically allocated objects
   Engine::global_unwind();

// and unload any DLLs
   Builtin::finis();  

#ifdef _WCON
// *add 1.2.8 inform the IDE that we're going down... 
   IDE::ucw_shut_down();
#endif
}

int Main::interactive_loop()
{
  for(;;) {
    if (call_parser()==FAIL) {
   //*  if (! interactive_mode()) return -1;// bail out if in batch mode
    } else return 0;// successful exit!
  }  
}

////////// MAIN ///////////////
#ifndef _USRDLL
int main(int argc, char **argv)
#else
int pgm_main(int argc, char **argv)
#endif  
//----------------------------
{
  using namespace Main;

  initialize();

 
  // *fix 1.2.3 Suppress irritating warning until we can decide what to do here!
  if (! process_command_line(argc, argv)) return 0;

  if (interactive_mode()) {    
    banner();
    Input::open("CON");
    Input::set_open_restore(NULL,setup_lib);
    const char* defs_file = (argc > 1) ? argv[1] : "defs.h";
    if (!Input::open(defs_file)) {
	   cmsg << "Now opening defs.h in UC home directory" << endl;
	   string uc_home = uc_home_dir();
       Utils::check_path_end(uc_home);
       string default_defs = uc_home + "defs.h";
       if (! Input::open(default_defs.c_str())) check_error();
    }  
  } else {
      // *add 1.2.9 Important to call these before/after routines
      // for initialization/finalization code to work properly.
      // *change 1.2.9a old behaviour
      set_on_open_restore(false);
      if (! Input::open(argv[1])) bail_out();
  }

// keep going until we end successfully!
  int retval = interactive_loop();
  if (retval == -1) return retval;
  if (! interactive_mode()) {
    mInteractiveMode = true;  // to force statement_end() to evaluate!
	Parser::init_lib();       // *fix 1.1.0 force any library initializations
    retval = Program::call_main(argc-1,argv+1,Program::new_window);
  }

  finalize();
  return retval;

}


⌨️ 快捷键说明

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