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

📄 main.cpp

📁 UC Library Extensions UnderC comes with a pocket implementation of the standard C++ libraries, wh
💻 CPP
📖 第 1 页 / 共 3 页
字号:
int module_open()
{ 
    string ext = Utils::file_extension(Module::current()->name());
    s_is_cpp_source = ext == ".c" || ext == ".cpp" || ext == ".cxx";
    s_last_c_mode = Parser::debug.c_mode;
    s_last_strict_mode = Parser::debug.strict;
    if (ext == ".c") Parser::set_c_mode(true);     
    Parser::debug.strict = s_is_cpp_source;
    Parser::debug.compile_program = s_is_cpp_source;
    Module::clean_namespaces();
    Module* pm = Module::current();
    pm->clean_macros_and_typedefs();
    // *change 1.2.9a Plain #l works as before; #lc creates __init functions etc.
    s_is_cpp_source = s_is_cpp_source && s_is_conditional;
    LoadedModuleList::init_module(s_is_cpp_source? pm->id() : -1);
    return 0;
}

// should always called!
int module_close()
{
    using namespace Parser;
    if (s_is_cpp_source ) {
      Instruction* pi;
      if (code().total_instructions() > 0) {
          code().emit_return(t_void);
          pi = code().end_code();
      } else pi = NULL;
      LoadedModuleList::finish_module(pi);      
    }
    s_is_cpp_source = false;
    Module::restore_namespaces();
    Parser::set_c_mode(s_last_c_mode);
    Parser::debug.strict = s_last_strict_mode;
    Parser::debug.compile_program = false;
    return 0;
}

static void set_on_open_restore(bool is_conditional)
{
   s_is_conditional = is_conditional;
   Input::set_open_restore(module_open,module_close);
}

extern Function* gLastFunction;  //*DEBUG - found in common.cpp

void __mangle()
{
 cerr << '_' << Mangle::GCC3(gLastFunction) << ';' << endl;
}

enum {CANT_OPEN, FILE_UNCHANGED, SUCCESS};

int compile_module(char *file, bool is_conditional)
{
// *fix 1.2.8 Make sure we're in global context before attempting a compilation
    bool is_break = Parser::current_function() != NULL;
    if (is_break) Parser::state.push_context(&Parser::global());
// *add 0.9.8 #l should now do a dependency check to allow changed headers to be included...
    Module *pm = Module::from_name(file);   
    if (!is_conditional) {
      if (pm != NULL) {
        Module::reset_modify_flags();
       // should we _always_ reload with #l?
       if (! pm->needs_rebuilding()) return FILE_UNCHANGED;
      }
    } else if (pm != NULL && ! pm->needs_rebuilding()) return FILE_UNCHANGED;
    //*DEBUG*
    if (is_conditional) {
      cmsg << "load: " << file;
      if (pm != NULL) cmsg << " id = " << pm->id();
      cmsg << endl;
    }
    set_on_open_restore(is_conditional);
    Parser::state.reset();
    if (is_break) Parser::state.pop_context();
    return Input::open(file) ? SUCCESS : CANT_OPEN;
}

int yylex(); // further along here...


extern bool tok_dbg;

bool UCTokenStream::user_cmd(string ppd)
{ 
  static string current_file;
  if (ppd == "q") return false; else
#ifdef _WCON
  if (ppd == "ql") { 
    wcon_copy_to_log(get_temp_log());
    return false;
  } else
#endif
  // *add 1.1.2 #pragma! Just dlink and pack()
    // *fix 1.2.0 it's not an error to leave out the library name
  if (ppd == "pragma") {	   
	  char *line = get_upto(0,false);
	  string what = strtok(line," ()");
	  char *arg   = strtok(NULL," ()");
	  if (what == "dlink") {
         if (!Builtin::set_current_lib_file(arg)) return cant_open_err(arg);
         char *impf = strtok(NULL," ()");
         if (impf != NULL) Builtin::generate_ordinal_lookup(impf);
      } else
	  if (what == "pack") Parser::set_alignment(atoi(arg));
#ifdef _DEBUG
      else
      if (what == "break") {
        gDebugBreak = atoi(arg);
        if (gDebugBreak == 1) {
          __break(1);
          gDebugBreak = 0;
        }
      } 
#endif
  } else
  if (ppd == "x") uc_system(get_upto(0,false)); else
  if (ppd == "cd") {
     Utils::change_dir(Input::next_token(true));
  } else
  if (ppd == "pwd") {
     cmsg << Utils::get_curr_dir() << endl;      
  } else
  if (ppd == "l" || ppd == "lc") {
    Errors::reset_error_state();
    char *cfile = Input::next_token();
    if (cfile) current_file = cfile;
    else if (current_file[0] != '\0') cfile = current_file.c_str();
    else return command_error("Please supply file\n");
    bool condn = ppd == "lc";
    int ret = compile_module(cfile,condn);
    
    if (ret == CANT_OPEN && !condn) cant_open_err(cfile);
    else if (ret == FILE_UNCHANGED) cmsg << "unchanged\n"; 
  } else 
  if (ppd == "bl") {
   // *add 0.9.4 Use this before a series of #lc commands...
    Module::reset_modify_flags();
  } else
 // *add 1.2.8 the #args command can be used to set commmand-line args for debugging;
 // after #args, the #r commands will use it as the default, unless overriden.
  if (ppd == "r" || ppd == "rx" || ppd == "args") {
     char* args = get_upto(0,false);
     if (ppd=="args") gCurrentArgs = strdup(args);
     else { // run the program (rx means 'don't run in separate thread'
       if (*args == '\0' && gCurrentArgs != NULL) args = strdup(gCurrentArgs);
       if (!Program::run(args,ppd=="rx")) cant_find("main");
     }
  } else
#ifdef _WCON
  if (ppd == "log") {
     wcon_copy_to_log(Input::next_token());
  } else
#endif
  if (ppd == "lib") {
    char *libf = Input::next_token();
    if (!Builtin::set_current_lib_file(libf)) cant_open_err(libf);
    char *impf = Input::next_token(false);
    // *fix 1.2.5 we were attempting to read an ordinal file after an empty #lib
    if (libf) {
      if (impf != NULL) Builtin::generate_ordinal_lookup(impf);
    }
  } else
  if (ppd == "opt") {
     char *line = get_upto(0,false);
     char *opt = strtok(line,", ");
     while (opt) { 
      char ch = *opt++;
      bool is_on = *opt == '+';
      bool strip_prompt, block_ide, change_block_ide = false;
      switch(ch) {
      case 'u': Parser::debug.auto_dissemble = is_on; break;
      case 'd': Parser::debug.dump_expr = is_on; break;
      case 'x': Parser::debug.auto_exec = is_on; break;
      case 't': Parser::debug.function_trace = is_on; break;
      case '4': Parser::debug.class_dword_align = is_on ? 4 : 1; break;
      case 'v': Parser::debug.verbose = is_on; tok_dbg = is_on; break;
      case 's': Parser::debug.strict = is_on; break;
      case 'p': Parser::debug.ptr_check = is_on; break;
      case 'a': Parser::debug.no_access_control = is_on; break; 
      case 'c': strip_prompt = is_on; break;
      case 'q': block_ide = is_on; change_block_ide = true; break;
      case 'C': Parser::set_c_mode(is_on); break;
      case 'T': Parser::debug.use_typedef_names = is_on; break;
      case 'L': Parser::debug.suppress_link_errors = is_on;  break;
      case 'i': Parser::debug.interactive_debugging = is_on; break;
      case 'S': Parser::debug.no_trace_std = is_on; break;
      case 'e': Parser::debug.errors_as_break = is_on; break; 
      case 'R': Parser::debug.range_check = is_on;  break;
      // temporary debugging options go here...
      }
      opt = strtok(NULL,", ");     
#ifdef _WCON
      // defaults initially to being on....
      if (strip_prompt) wcon_prompt_char(';',0);
                  else wcon_prompt_char(0,0);
      if (change_block_ide) IDE::set_blocking(block_ide);
#endif
    }
  } else
  if (ppd == "lv") {
    display_locals(NULL,NULL,false,Input::next_token() != NULL);
  } else
// *add 1.2.8 #dl <obj> shows only _local_ fields, not inherited as well.
    if (ppd == "d" || ppd == "dl") { 
    PEntry pe = Input::lookup_next_symbol(); 
    if (pe == NULL)  return cant_find("symbol");
    Type t = pe->type;
    if (!t.is_class()) return command_error("Not an object");
    void *ptr = pe->global_ptr();
    display_locals(t.as_class(),ptr,t.is_ref_or_ptr(), ppd == "d");
  } else
  if (ppd == "rm") { // remove symbol or program
     PEntry pe = Input::lookup_next_symbol();
     if (pe->type.is_function()) { // this was a function
        if (pe->name=="main") Breakpoint::remove_all();  // *add 0.9.8 remove program and clear out breakpoints
        FunctionEntry* pfe = reinterpret_cast<FunctionEntry *>(pe->data);
        int imod = pfe->back()->line_nos()->module();
        Module *pm = Module::from_id(imod);
        if (pm != NULL) Module::remove(pm);
     } 
     if (pe == NULL) return cant_find("symbol");
     Parser::global().remove(pe);     
  } else
  if (ppd == "s") { // *add 0.9.4 Now can stop runaway programs w/ #s
#ifdef _WCON
     Program::stop_main(false); // *change 1.2.8 no longer an error
#endif
  } else
  if (ppd == "st" || ppd == "sto") { // *add 1.1.4 Single-stepping through programs!
      s_single_step = true;  
      Engine::set_single_stepping(ppd == "st");      
      Program::run(gCurrentArgs,false /*Input::next_token() == NULL*/);
  } else
  if (ppd == "clr") { // clear input (0) or console (1)
#ifdef _WCON
      wcon_clear(safe_atoi(Input::next_token()));
#endif 
// otherwise need some portable way of doing clr 0?
  } else
  if (ppd == "attach") {
    //	  char *fn = Input::next_token();
    //	  attach_main_context(fn); 
  } else
  if (ppd == "mod") {
      char *fun = Input::next_token();
      if (fun == NULL) Module::dump_entries(cmsg,0);
      else {
         // Module *pm = Module::from_name(file);
         // if(pm == NULL) cant_find(file);
         // else pm->dump(*msg,Module::FUNS | Module::DEPEND);
         string file;
         // *change 0.9.4  #mod name gives defn pos. of function 'name'
         int ln = Module::file_from_function(Function::lookup(fun),file);
         cmsg << file << ' ' << ln << endl;
      }
  } else
  if (ppd == "types" || ppd == "funs") {
	  char *pat = Input::next_token();
	  EntryList el;
	  if (pat == NULL) pat = "*";
	  Parser::global().search_entries(pat,&el,(ppd == "funs") ? FUNCTIONS : (CLASSES | NAMESPACES | TYPEDEFS));
	  EntryList::iterator eli;
	  FORALL(eli,el) cmsg << (*eli)->name << endl;
  } else
  if (ppd == "gt" || ppd == "b") {
      Errors::reset_error_state();
      int lineno = safe_atoi(Input::next_token());
      char *file = Input::next_token(false);
      if (file == NULL) file = current_file.c_str();  // set by #l, etc
      //cout << "b " << file << ':' << lineno << endl;
      Breakpoint::toggle(file,lineno,ppd == "b",cmsg);
  } else
  if (ppd == "bs") { // set a number of breakpoints in a file   
     Errors::reset_error_state();
     char *tok, *file = Input::next_token();
     int lines[10], i = 0;
     while ((tok = Input::next_token(false)) != NULL)
         lines[i++] = safe_atoi(tok);
     if (i == 0) { // this is a _request_!!
         Breakpoint::group(file,lines,i,true);
         cmsg << i << ' ';
         for (int k = 0; k < i; k++) cmsg << lines[k] << ' ';
         cmsg << endl;
     } else
     Breakpoint::group(file,lines,i,false);
  } else
  if (ppd == "ff") {
      Engine::set_frame(safe_atoi(Input::next_token(true)),true);
      if (! Parser::debug.interactive_debugging)
        display_locals(NULL,NULL);
  } else
  if (ppd == "fs") {
    dump_fun_stack();
  }
  else
  if (ppd == "u" || ppd == "mm" || ppd == "fe") {
    // char *name = next_token();
     PEntry pe = Input::lookup_next_symbol();
     if (pe == NULL) return true; 
     int idx = safe_atoi(Input::next_token(true));
     if (pe->type.is_function()) {
         if (ppd == "u") Parser::dump_function(pe,true,idx,cout);        
         else {
           Function *pf = *(((FunctionEntry *)pe->data)->begin());
           if (ppd == "fe") {
             FBlock *fb = pf->fun_block();
             fb->nlocal = idx;
           } else {
        //    cout << "MS:  " << Mangle::microsoft(pf) << endl;
			cout << Mangle::GCC3(pf) << endl;
           }
         }
     } 
  } else
  if (ppd == "v") { // inspect - used to be 'var'!!
     PEntry pe = Input::lookup_next_symbol();
     if (pe==NULL) return true;
     Parser::dump_var(pe);
  } else
  if (ppd == "tx") { //*TEST*
      redirected_eval(get_upto(0,false),false);
  }
  else
  if (ppd == "rx") { //*TEST*
     ext_run_program(get_upto(0,false),false);
  }
  else
  if (ppd == "vmt") {
    PEntry pe = Input::lookup_next_symbol(); 
    if (pe == NULL)  return true;
    Type t = pe->type;
    int *ptr = *(int **)pe->global_ptr();
    ptr--;  // now at hidden pointer...
    PClass pc = t.as_class();
    if (! pc->has_VMT()) cout << "No VMT\n";
    cout << "name " << pc->name() << " " << pc->last_slot() << endl;         
	for(int i = 1; i < pc->last_slot(); i++) {
	   cout << i << ' ';
	   ((Function *)ptr[i])->dump(cout);
	   cout << endl;	  
    }
  }
  else 
  if (ppd == "unload") {
      Builtin::unload_lib(Builtin::get_dll_handle());
  }
  else
  if (ppd == "mc") { macro_cleanup(); clear_global_namespace(); }
  else
  if (ppd == "unwind") { Engine::global_unwind(); }
  else // *add 1.2.9 Module trace back list
  if (ppd == "trace_back") { dump_module_traceback(); }

⌨️ 快捷键说明

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