// --------------------------------------------------------------------------- // - Debugger.hpp - // - afnix cross debugger - debugger class implementation - // --------------------------------------------------------------------------- // - This program is free software; you can redistribute it and/or modify - // - it provided that this copyright notice is kept intact. - // - - // - This program is distributed in the hope that it will be useful, but - // - without any warranty; without even the implied warranty of - // - merchantability or fitness for a particular purpose. In no event shall - // - the copyright holder be liable for any direct, indirect, incidental or - // - special damages arising in any way out of the use of this software. - // --------------------------------------------------------------------------- // - copyright (c) 1999-2007 amaury darsch - // --------------------------------------------------------------------------- #include "System.hpp" #include "Module.hpp" #include "Return.hpp" #include "Resume.hpp" #include "Integer.hpp" #include "Function.hpp" #include "Axdcalls.hpp" #include "Debugger.hpp" namespace afnix { // debugger default prompts static const char* DEFAULT_PROMPT1 = "(axd) "; static const char* DEFAULT_PROMPT2 = "(...) "; // create a default debugger Debugger::Debugger (void) { // initialize the debugger mode d_emacs = false; d_start = false; d_finish = false; d_exit = false; d_vflag = true; d_lmax = 10; p_form = nilp; // initialize the terminal if (p_term != nilp) { p_term->setpp (DEFAULT_PROMPT1); p_term->setsp (DEFAULT_PROMPT2); p_term->setigneof (true); } // initialize the reader Object::iref (p_reader = new Reader (getis ())); // bind the axd nameset Object::iref (p_aset = mknset ("axd")); // bind the i-files nameset Object::iref (p_iset = p_aset->mknset ("i-files")); // bind the commands in the axd nameset p_aset->symcst ("run", new Function (axd_run)); p_aset->symcst ("load", new Function (axd_ldf)); p_aset->symcst ("exit", new Function (axd_xit)); p_aset->symcst ("quit", new Function (axd_xit)); p_aset->symcst ("next", new Function (axd_nxt)); p_aset->symcst ("break", new Function (axd_bpt)); p_aset->symcst ("list", new Function (axd_lst)); p_aset->symcst ("info", new Function (axd_ifo)); p_aset->symcst ("continue", new Function (axd_cnt)); p_aset->symcst ("break-info", new Function (axd_bfo)); } // destroy this debugger Debugger::~Debugger (void) { d_bpoint.reset (); if (p_iset != nilp) p_iset->reset (); if (p_aset != nilp) p_aset->reset (); Object::dref (p_form); Object::dref (p_iset); Object::dref (p_aset); Object::dref (p_reader); } // set the emacs info mode void Debugger::setemacs (const bool mode) { wrlock (); d_emacs = mode; unlock (); } // return the start flag bool Debugger::getstart (void) const { rdlock (); bool result = d_start; unlock (); return result; } // set the exit flag void Debugger::setexit (const bool flag) { wrlock (); d_exit = flag; unlock (); } // set the initial file name void Debugger::setinitial (const String& fname) { wrlock (); try { if (fname.length () != 0) { Ifile* ifile = instrument (fname); if ((ifile != nilp) && (ifile->length () > 0)) { Form* form = ifile->getform(0); if (form != nilp) { Object::iref (form); Object::dref (p_form); p_form = form; String name = form->getname (); long lnum = form->getlnum (); info (name, lnum); } } d_fname = fname; } unlock (); } catch (...) { unlock (); throw; } } // run the program as specified in the initial file name void Debugger::runinitial (void) { if (d_fname.length () == 0) throw Exception ("axd-error", "no initial file specified"); d_start = true; load (d_fname); } // instrument a file and return an instrumented file object Ifile* Debugger::instrument (const String& fname) { wrlock (); try { // create a new module reader Input* ms = p_rslv->alplkp (fname); String mn = p_rslv->alpname (fname); Module mp (ms, mn); // bind the instrumented file Ifile* ifile = new Ifile (mp); if (ifile != nilp) p_iset->bind (mn, ifile); unlock (); return ifile; } catch (...) { unlock (); throw; } } // break the debugger in a nameset with an object bool Debugger::bpt (Nameset* nset, Object* object) { // check for a form Form* form = dynamic_cast