/* * Set breakpoint and stack markers for a file */ static void set_markers_for_file(const gchar* file) { GList *breaks; if ( (breaks = breaks_get_for_document(file)) ) { GList *iter = breaks; while (iter) { breakpoint *bp = (breakpoint*)iter->data; markers_add_breakpoint(bp); iter = iter->next; } g_list_free(breaks); } /* set frames markers if exists */ if (DBS_STOPPED == debug_get_state()) { int active_frame_index = debug_get_active_frame(); GList *iter = debug_get_stack(); int frame_index = 0; for (; iter; iter = iter->next, frame_index++) { if (iter) { frame *f = (frame*)iter->data; if (f->have_source && !strcmp(f->file, file)) { if (active_frame_index == frame_index) { markers_add_current_instruction(f->file, f->line); } else { markers_add_frame(f->file, f->line); } } } } } }
/* * sets all breakpoints fo the file enabled or disabled. * arguments: * file - list of breakpoints * enabled - anble or disable breakpoints */ void breaks_set_enabled_for_file(const const char *file, gboolean enabled) { /* do not process async break manipulation on modules that do not support async interuppt */ enum dbs state = debug_get_state(); if (DBS_RUNNING == state && !debug_supports_async_breaks()) return; GList *breaks = breaks_get_for_document(file); /* handle switching instantly if debugger is idle or stopped and request debug module interruption overwise */ if (DBS_IDLE == state) { on_set_enabled_list(breaks, enabled); g_list_free(breaks); config_set_debug_changed(); } else if (DBS_STOPPED == state) enabled ? breaks_set_enabled_list_debug(breaks) : breaks_set_disabled_list_debug(breaks); else if (DBS_STOP_REQUESTED != state) debug_request_interrupt((bs_callback)(enabled ? breaks_set_enabled_list_debug : breaks_set_disabled_list_debug), (gpointer)breaks); }
/* * Occures on notify from editor. * Handles margin click to set/remove breakpoint */ gboolean on_editor_notify( GObject *object, GeanyEditor *editor, SCNotification *nt, gpointer data) { if (!editor->document->real_path) { /* no other way to handle removing a file from outside of geany */ markers_remove_all(editor->document); } switch (nt->nmhdr.code) { case SCN_MARGINCLICK: { char* file; int line; break_state bs; if (!editor->document->real_path || 1 != nt->margin) break; file = editor->document->file_name; line = sci_get_line_from_position(editor->sci, nt->position) + 1; bs = breaks_get_state(file, line); if (BS_NOT_SET == bs) breaks_add(file, line, NULL, TRUE, 0); else if (BS_ENABLED == bs) breaks_remove(file, line); else if (BS_DISABLED == bs) breaks_switch(file, line); scintilla_send_message(editor->sci, SCI_SETFOCUS, TRUE, 0); return TRUE; } case SCN_DWELLSTART: { GString *word; if (DBS_STOPPED != debug_get_state ()) break; /* get a word under the cursor */ word = get_word_at_position(editor->sci, nt->position); if (word->len) { gchar *calltip = debug_get_calltip_for_expression(word->str); if (calltip) { leave_signal = g_signal_connect(G_OBJECT(editor->sci), "leave-notify-event", G_CALLBACK(on_mouse_leave), NULL); scintilla_send_message (editor->sci, SCI_CALLTIPSHOW, nt->position, (long)calltip); } } g_string_free(word, TRUE); break; } case SCN_DWELLEND: { if (DBS_STOPPED != debug_get_state ()) break; if (scintilla_send_message (editor->sci, SCI_CALLTIPACTIVE, 0, 0)) { g_signal_handler_disconnect(G_OBJECT(editor->sci), leave_signal); scintilla_send_message (editor->sci, SCI_CALLTIPCANCEL, 0, 0); } break; } case SCN_MODIFYATTEMPTRO: { dialogs_show_msgbox(GTK_MESSAGE_INFO, _("To edit source files stop debugging session")); break; } case SCN_MODIFIED: { if(((SC_MOD_INSERTTEXT & nt->modificationType) || (SC_MOD_DELETETEXT && nt->modificationType)) && editor->document->file_name && nt->linesAdded) { int line = sci_get_line_from_position(editor->sci, nt->position) + 1; GList *breaks = breaks_get_for_document(editor->document->file_name); if (breaks) { GList *iter = breaks; while (iter) { breakpoint *bp = (breakpoint*)iter->data; if (nt->linesAdded > 0 && bp->line >= line) { breaks_move_to_line(bp->file, bp->line, bp->line + nt->linesAdded); bptree_update_breakpoint(bp); } else if (nt->linesAdded < 0 && bp->line >= line) { if (bp->line < line - nt->linesAdded) { breaks_remove(bp->file, bp->line); } else { breaks_move_to_line(bp->file, bp->line, bp->line + nt->linesAdded); bptree_update_breakpoint(bp); } } iter = iter->next; } config_set_debug_changed(); g_list_free(breaks); } } break; } } return FALSE; }