Browse Source

Added Show Variables in Debug menu

merge-requests/365/head
Ole Christian Eidheim 10 years ago
parent
commit
bc7fcdf01d
  1. 42
      src/debug.cc
  2. 10
      src/debug.h
  3. 3
      src/files.h
  4. 5
      src/menu.cc
  5. 14
      src/selectiondialog.cc
  6. 1
      src/selectiondialog.h
  7. 89
      src/window.cc
  8. 3
      src/window.h

42
src/debug.cc

@ -318,6 +318,48 @@ std::vector<Debug::Frame> Debug::get_backtrace() {
return backtrace; return backtrace;
} }
std::vector<Debug::Variable> Debug::get_variables() {
vector<Debug::Variable> variables;
event_mutex.lock();
if(state==lldb::StateType::eStateStopped) {
for(uint32_t c_t=0;c_t<process->GetNumThreads();c_t++) {
auto thread=process->GetThreadAtIndex(c_t);
for(uint32_t c_f=0;c_f<thread.GetNumFrames();c_f++) {
auto frame=thread.GetFrameAtIndex(c_f);
auto values=frame.GetVariables(true, true, true, false);
for(uint32_t value_index=0;value_index<values.GetSize();value_index++) {
lldb::SBStream stream;
auto value=values.GetValueAtIndex(value_index);
auto declaration=value.GetDeclaration();
if(declaration.IsValid()) {
Debug::Variable variable;
variable.frame_index=c_f;
variable.name=value.GetName();
variable.line_nr=declaration.GetLine();
variable.line_index=declaration.GetColumn();
if(variable.line_index==0)
variable.line_index=1;
auto file_spec=declaration.GetFileSpec();
variable.file_path=file_spec.GetDirectory();
variable.file_path/=file_spec.GetFilename();
value.GetDescription(stream);
variable.value=stream.GetData();
variables.emplace_back(variable);
}
}
}
}
}
event_mutex.unlock();
return variables;
}
void Debug::select_frame(uint32_t index) { void Debug::select_frame(uint32_t index) {
event_mutex.lock(); event_mutex.lock();
if(state==lldb::StateType::eStateStopped) { if(state==lldb::StateType::eStateStopped) {

10
src/debug.h

@ -20,6 +20,15 @@ public:
int line_nr; int line_nr;
int line_index; int line_index;
}; };
class Variable {
public:
uint32_t frame_index;
std::string name;
std::string value;
boost::filesystem::path file_path;
int line_nr;
int line_index;
};
private: private:
Debug(); Debug();
public: public:
@ -41,6 +50,7 @@ public:
void step_out(); void step_out();
std::pair<std::string, std::string> run_command(const std::string &command); std::pair<std::string, std::string> run_command(const std::string &command);
std::vector<Frame> get_backtrace(); std::vector<Frame> get_backtrace();
std::vector<Variable> get_variables();
void select_frame(uint32_t index); void select_frame(uint32_t index);
void delete_debug(); //can't use delete as function name void delete_debug(); //can't use delete as function name

3
src/files.h

@ -2,7 +2,7 @@
#define JUCI_FILES_H_ #define JUCI_FILES_H_
#include <string> #include <string>
#define JUCI_VERSION "1.1.0-3" #define JUCI_VERSION "1.1.0-4"
const std::string configjson = const std::string configjson =
"{\n" "{\n"
@ -107,6 +107,7 @@ const std::string configjson =
" \"debug_step_into\": \"<primary>t\",\n" " \"debug_step_into\": \"<primary>t\",\n"
" \"debug_step_out\": \"<primary><shift>t\",\n" " \"debug_step_out\": \"<primary><shift>t\",\n"
" \"debug_backtrace\": \"<primary><shift>j\",\n" " \"debug_backtrace\": \"<primary><shift>j\",\n"
" \"debug_show_variables\": \"<primary><shift>b\",\n"
" \"debug_run_command\": \"<alt><shift>Return\",\n" " \"debug_run_command\": \"<alt><shift>Return\",\n"
" \"debug_toggle_breakpoint\": \"<primary>b\",\n" " \"debug_toggle_breakpoint\": \"<primary>b\",\n"
" \"debug_goto_stop\": \"<primary><shift>l\",\n" " \"debug_goto_stop\": \"<primary><shift>l\",\n"

5
src/menu.cc

@ -320,6 +320,11 @@ Menu::Menu() {
" <attribute name='action'>app.debug_backtrace</attribute>" " <attribute name='action'>app.debug_backtrace</attribute>"
+accels["debug_backtrace"]+ //For Ubuntu... +accels["debug_backtrace"]+ //For Ubuntu...
" </item>" " </item>"
" <item>"
" <attribute name='label' translatable='yes'>_Show _Variables</attribute>"
" <attribute name='action'>app.debug_show_variables</attribute>"
+accels["debug_show_variables"]+ //For Ubuntu...
" </item>"
" </section>" " </section>"
" <section>" " <section>"
" <item>" " <item>"

14
src/selectiondialog.cc

@ -72,6 +72,18 @@ list_view_text(use_markup), start_mark(start_mark), show_search_entry(show_searc
}); });
} }
list_view_text.signal_cursor_changed().connect([this]() {
if(!shown)
return;
auto it=list_view_text.get_selection()->get_selected();
if(it) {
std::string row;
it->get_value(0, row);
if(on_changed)
on_changed(row);
}
});
scrolled_window.add(list_view_text); scrolled_window.add(list_view_text);
if(!show_search_entry) if(!show_search_entry)
window->add(scrolled_window); window->add(scrolled_window);
@ -102,13 +114,13 @@ void SelectionDialogBase::show() {
void SelectionDialogBase::hide() { void SelectionDialogBase::hide() {
if(!shown) if(!shown)
return; return;
shown=false;
window->hide(); window->hide();
if(tooltips) if(tooltips)
tooltips->hide(); tooltips->hide();
if(on_hide) if(on_hide)
on_hide(); on_hide();
list_view_text.clear(); list_view_text.clear();
shown=false;
} }
void SelectionDialogBase::update_tooltips() { void SelectionDialogBase::update_tooltips() {

1
src/selectiondialog.h

@ -35,6 +35,7 @@ public:
virtual void move(); virtual void move();
std::function<void()> on_hide; std::function<void()> on_hide;
std::function<void(const std::string &selected)> on_changed;
std::function<void(const std::string& selected, bool hide_window)> on_select; std::function<void(const std::string& selected, bool hide_window)> on_select;
Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark; Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark;

89
src/window.cc

@ -154,6 +154,7 @@ Window::Window() : compiling(false), debugging(false) {
menu.actions["debug_step_into"]->set_enabled(false); menu.actions["debug_step_into"]->set_enabled(false);
menu.actions["debug_step_out"]->set_enabled(false); menu.actions["debug_step_out"]->set_enabled(false);
menu.actions["debug_backtrace"]->set_enabled(false); menu.actions["debug_backtrace"]->set_enabled(false);
menu.actions["debug_show_variables"]->set_enabled(false);
menu.actions["debug_run_command"]->set_enabled(false); menu.actions["debug_run_command"]->set_enabled(false);
menu.actions["debug_goto_stop"]->set_enabled(false); menu.actions["debug_goto_stop"]->set_enabled(false);
#endif #endif
@ -168,6 +169,7 @@ Window::Window() : compiling(false), debugging(false) {
menu.actions["debug_step_into"]->set_enabled(false); menu.actions["debug_step_into"]->set_enabled(false);
menu.actions["debug_step_out"]->set_enabled(false); menu.actions["debug_step_out"]->set_enabled(false);
menu.actions["debug_backtrace"]->set_enabled(false); menu.actions["debug_backtrace"]->set_enabled(false);
menu.actions["debug_show_variables"]->set_enabled(false);
menu.actions["debug_run_command"]->set_enabled(false); menu.actions["debug_run_command"]->set_enabled(false);
menu.actions["debug_goto_stop"]->set_enabled(false); menu.actions["debug_goto_stop"]->set_enabled(false);
} }
@ -180,6 +182,7 @@ Window::Window() : compiling(false), debugging(false) {
menu.actions["debug_step_into"]->set_enabled(); menu.actions["debug_step_into"]->set_enabled();
menu.actions["debug_step_out"]->set_enabled(); menu.actions["debug_step_out"]->set_enabled();
menu.actions["debug_backtrace"]->set_enabled(); menu.actions["debug_backtrace"]->set_enabled();
menu.actions["debug_show_variables"]->set_enabled();
menu.actions["debug_run_command"]->set_enabled(); menu.actions["debug_run_command"]->set_enabled();
menu.actions["debug_goto_stop"]->set_enabled(); menu.actions["debug_goto_stop"]->set_enabled();
} }
@ -953,6 +956,92 @@ void Window::set_menu_actions() {
view->selection_dialog->show(); view->selection_dialog->show();
} }
}); });
menu.add_action("debug_show_variables", [this]() {
if(debugging && notebook.get_current_page()!=-1) {
auto variables=Debug::get().get_variables();
auto view=notebook.get_current_view();
auto buffer=view->get_buffer();
auto iter=buffer->get_insert()->get_iter();
if(iter.get_line_offset()>=80)
iter=buffer->get_iter_at_line(iter.get_line());
Gdk::Rectangle visible_rect;
view->get_visible_rect(visible_rect);
Gdk::Rectangle iter_rect;
view->get_iter_location(iter, iter_rect);
iter_rect.set_width(1);
if(!visible_rect.intersects(iter_rect)) {
view->get_iter_at_location(iter, 0, visible_rect.get_y()+visible_rect.get_height()/3);
}
view->selection_dialog=std::unique_ptr<SelectionDialog>(new SelectionDialog(*view, buffer->create_mark(iter), true, true));
auto rows=std::make_shared<std::unordered_map<std::string, Debug::Variable> >();
if(variables.size()==0)
return;
for(auto &variable: variables) {
std::string row=variable.file_path.filename().string()+":"+std::to_string(variable.line_nr)+" - <b>"+Glib::Markup::escape_text(variable.name)+"</b>";
(*rows)[row]=variable;
view->selection_dialog->add_row(row);
}
view->selection_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) {
auto variable=rows->at(selected);
if(!variable.file_path.empty()) {
notebook.open(variable.file_path);
if(notebook.get_current_page()!=-1) {
auto view=notebook.get_current_view();
Debug::get().select_frame(variable.frame_index);
view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(variable.line_nr-1, variable.line_index-1));
while(g_main_context_pending(NULL))
g_main_context_iteration(NULL, false);
if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view)
view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
}
}
};
view->selection_dialog->on_hide=[this]() {
if(debug_variable_tooltips) {
debug_variable_tooltips->hide();
debug_variable_tooltips.reset();
}
};
view->selection_dialog->on_changed=[this, rows, iter](const std::string &selected) {
if(notebook.get_current_page()!=-1) {
auto view=notebook.get_current_view();
debug_variable_tooltips=std::unique_ptr<Tooltips>(new Tooltips());
auto create_tooltip_buffer=[this, rows, view, selected]() {
auto variable=rows->at(selected);
auto tooltip_buffer=Gtk::TextBuffer::create(view->get_buffer()->get_tag_table());
Glib::ustring value=variable.value;
if(!value.empty()) {
Glib::ustring::iterator iter;
while(!value.validate(iter)) {
auto next_char_iter=iter;
next_char_iter++;
value.replace(iter, next_char_iter, "?");
}
tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), value.substr(0, value.size()-1), "def:note");
}
return tooltip_buffer;
};
debug_variable_tooltips->emplace_back(create_tooltip_buffer, *view, view->get_buffer()->create_mark(iter), view->get_buffer()->create_mark(iter));
debug_variable_tooltips->show(true);
}
};
view->selection_dialog->show();
}
});
menu.add_action("debug_run_command", [this]() { menu.add_action("debug_run_command", [this]() {
entry_box.clear(); entry_box.clear();
entry_box.entries.emplace_back(last_run_debug_command, [this](const std::string& content){ entry_box.entries.emplace_back(last_run_debug_command, [this](const std::string& content){

3
src/window.h

@ -5,6 +5,7 @@
#include "entrybox.h" #include "entrybox.h"
#include "notebook.h" #include "notebook.h"
#include "cmake.h" #include "cmake.h"
#include "tooltips.h"
#include <atomic> #include <atomic>
class Window : public Gtk::ApplicationWindow { class Window : public Gtk::ApplicationWindow {
@ -47,6 +48,8 @@ private:
std::mutex debug_status_mutex; std::mutex debug_status_mutex;
Glib::Dispatcher debug_update_status; Glib::Dispatcher debug_update_status;
std::unique_ptr<Tooltips> debug_variable_tooltips;
std::unique_ptr<CMake> get_cmake(); std::unique_ptr<CMake> get_cmake();
std::unordered_map<std::string, std::string> project_run_arguments; std::unordered_map<std::string, std::string> project_run_arguments;
std::unordered_map<std::string, std::string> debug_run_arguments; std::unordered_map<std::string, std::string> debug_run_arguments;

Loading…
Cancel
Save