From 20c769b06373ebb0956643478fb8f33dea6ae190 Mon Sep 17 00:00:00 2001 From: Ilia Maslakov Date: Wed, 25 Feb 2009 21:53:52 +0000 Subject: [PATCH 01/14] Add stack navigation structure. Add hotkeys A-'-' backward A-'=' forward navigation to files. add edit/etags.c edit/etags.h --- edit/Makefile.am | 2 +- edit/edit.c | 35 +++++++++ edit/edit.h | 10 +++ edit/editcmd.c | 185 +++++++++++++++++++++++++++++++++++++++++++++- edit/editcmddef.h | 5 +- edit/editkeys.c | 4 +- edit/etags.c | 88 ++++++++++++++++++++++ edit/etags.h | 9 +++ src/main.c | 18 +++++ src/main.h | 9 +++ 10 files changed, 360 insertions(+), 5 deletions(-) create mode 100644 edit/etags.c create mode 100644 edit/etags.h diff --git a/edit/Makefile.am b/edit/Makefile.am index 2fd8a4ab1..ce828716a 100644 --- a/edit/Makefile.am +++ b/edit/Makefile.am @@ -10,6 +10,6 @@ libedit_a_SOURCES = \ bookmark.c edit.c editcmd.c editwidget.c editdraw.c editkeys.c \ editmenu.c editoptions.c editcmddef.h edit.h edit-widget.h \ editlock.c editlock.h syntax.c usermap.h usermap.c wordproc.c \ - choosesyntax.c + choosesyntax.c etags.c etats.h EXTRA_DIST = ChangeLog diff --git a/edit/edit.c b/edit/edit.c index 51810f793..2b8820428 100644 --- a/edit/edit.c +++ b/edit/edit.c @@ -646,6 +646,31 @@ edit_reload (WEdit *edit, const char *filename) return 1; } +/* + * Load a new file into the editor and set line. If it fails, preserve the old file. + * To do it, allocate a new widget, initialize it and, if the new file + * was loaded, copy the data to the old widget. + * Return 1 on success, 0 on failure. + */ +int +edit_reload_line (WEdit *edit, const char *filename, long line) +{ + WEdit *e; + int lines = edit->num_widget_lines; + int columns = edit->num_widget_columns; + + e = g_malloc0 (sizeof (WEdit)); + e->widget = edit->widget; + if (!edit_init (e, lines, columns, filename, line)) { + g_free (e); + return 0; + } + edit_clean (edit); + memcpy (edit, e, sizeof (WEdit)); + g_free (e); + return 1; +} + /* Recording stack for undo: @@ -2480,6 +2505,13 @@ edit_execute_cmd (WEdit *edit, int command, int char_for_insertion) edit_insert_file_cmd (edit); break; + case CK_Load_Prev_File: + edit_load_back_cmd (edit); + break; + case CK_Load_Next_File: + edit_load_forward_cmd (edit); + break; + case CK_Toggle_Syntax: if ((option_syntax_highlighting ^= 1) == 1) edit_load_syntax (edit, NULL, option_syntax_type); @@ -2501,6 +2533,9 @@ edit_execute_cmd (WEdit *edit, int command, int char_for_insertion) case CK_Complete_Word: edit_complete_word_cmd (edit); break; + case CK_Find_Definition: + edit_get_match_keyword_cmd (edit); + break; case CK_Exit: dlg_stop (edit->widget.parent); diff --git a/edit/edit.h b/edit/edit.h index 3e5f5637e..85fd07af0 100644 --- a/edit/edit.h +++ b/edit/edit.h @@ -103,6 +103,14 @@ #define TAB_SIZE option_tab_spacing #define HALF_TAB_SIZE ((int) option_tab_spacing / 2) +/* max count stack files */ +#define MAX_HISTORY_MOVETO 50 + +typedef struct edit_stack_type { + long line; + char *filename; +}edit_stack_type; + struct macro { short command; short ch; @@ -175,6 +183,8 @@ int edit_save_block (WEdit * edit, const char *filename, long start, long finish int edit_save_block_cmd (WEdit * edit); int edit_insert_file_cmd (WEdit * edit); int edit_insert_file (WEdit * edit, const char *filename); +int edit_load_back_cmd (WEdit * edit); +int edit_load_forward_cmd (WEdit * edit); void edit_block_process_cmd (WEdit * edit, const char *shell_cmd, int block); void freestrs (void); void edit_refresh_cmd (WEdit * edit); diff --git a/edit/editcmd.c b/edit/editcmd.c index 257ab6efe..a69cb89c3 100644 --- a/edit/editcmd.c +++ b/edit/editcmd.c @@ -1,4 +1,4 @@ -/* editor high level editing commands. +/* editor high level editing commands Copyright (C) 1996, 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. @@ -45,6 +45,7 @@ #include "editlock.h" #include "editcmddef.h" #include "edit-widget.h" +#include "etags.h" #include "../src/color.h" /* dialog_colors */ #include "../src/tty.h" /* LINES */ @@ -2795,6 +2796,7 @@ static void edit_completion_dialog (WEdit * edit, int max_len, int word_len, struct selection *compl, int num_compl) { + int start_x, start_y, offset, i; char *curr = NULL; Dlg_head *compl_dlg; @@ -2883,8 +2885,8 @@ edit_complete_word_cmd (WEdit *edit) /* prepare match expression */ bufpos = &edit->buffers1[word_start >> S_EDIT_BUF_SIZE] [word_start & M_EDIT_BUF_SIZE]; - match_expr = g_strdup_printf ("%.*s[a-zA-Z_0-9]+", word_len, bufpos); + match_expr = g_strdup_printf ("%.*s[a-zA-Z_0-9]+", word_len, bufpos); /* init search: backward, regexp, whole word, case sensitive */ edit_set_search_parameters (0, 1, 1, 1, 1); @@ -2969,3 +2971,182 @@ edit_begin_end_macro_cmd(WEdit *edit) edit_execute_key_command (edit, command, -1); } } + +int +edit_load_forward_cmd (WEdit *edit) +{ + if (edit->modified) { + if (edit_query_dialog2 + (_("Warning"), + _(" Current text was modified without a file save. \n" + " Continue discards these changes. "), _("C&ontinue"), + _("&Cancel"))) { + edit->force |= REDRAW_COMPLETELY; + return 0; + } + } + if ( edit_stack_iterator + 1 < MAX_HISTORY_MOVETO ) { + if ( edit_history_moveto[edit_stack_iterator + 1].line < 1 ) { + return 1; + } + edit_stack_iterator++; + if ( edit_history_moveto[edit_stack_iterator].filename ) { + edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename, + edit_history_moveto[edit_stack_iterator].line); + return 0; + } else { + return 1; + } + } else { + return 1; + } +} + +int +edit_load_back_cmd (WEdit *edit) +{ + if (edit->modified) { + if (edit_query_dialog2 + (_("Warning"), + _(" Current text was modified without a file save. \n" + " Continue discards these changes. "), _("C&ontinue"), + _("&Cancel"))) { + edit->force |= REDRAW_COMPLETELY; + return 0; + } + } + if ( edit_stack_iterator > 0 ) { + edit_stack_iterator--; + if ( edit_history_moveto[edit_stack_iterator].filename ) { + edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename, + edit_history_moveto[edit_stack_iterator].line); + return 0; + } else { + return 1; + } + } else { + return 1; + } +} + + +/* let the user select where function definition */ +static void +edit_select_definition_dialog (WEdit * edit, int max_len, int word_len, + struct def_hash_type *def_hash, int num_lines) +{ + + int start_x, start_y, offset, i; + char *curr = NULL; + struct def_hash_type *curr_def; + Dlg_head *def_dlg; + WListbox *def_list; + int def_dlg_h; /* dialog height */ + int def_dlg_w; /* dialog width */ + + /* calculate the dialog metrics */ + def_dlg_h = num_lines + 2; + def_dlg_w = max_len + 4; + start_x = edit->curs_col + edit->start_col - (def_dlg_w / 2); + start_y = edit->curs_row + EDIT_TEXT_VERTICAL_OFFSET + 1; + + if (start_x < 0) + start_x = 0; + if (def_dlg_w > COLS) + def_dlg_w = COLS; + if (def_dlg_h > LINES - 2) + def_dlg_h = LINES - 2; + + offset = start_x + def_dlg_w - COLS; + if (offset > 0) + start_x -= offset; + offset = start_y + def_dlg_h - LINES; + if (offset > 0) + start_y -= (offset + 1); + + /* create the dialog */ + def_dlg = create_dlg (start_y, start_x, def_dlg_h, def_dlg_w, + dialog_colors, NULL, "[Definitions]", NULL, + DLG_COMPACT); + + /* create the listbox */ + def_list = listbox_new (1, 1, def_dlg_w - 2, def_dlg_h - 2, NULL); + + /* add the dialog */ + add_widget (def_dlg, def_list); + + char *label_def = NULL; + + /* fill the listbox with the completions */ + for (i = 0; i < num_lines; i++) { + label_def = g_strdup_printf ("%s:%i", def_hash[i].filename, def_hash[i].line); + listbox_add_item (def_list, LISTBOX_APPEND_AT_END, 0, label_def, &def_hash[i]); + g_free(label_def); + } + /* pop up the dialog */ + run_dlg (def_dlg); + + /* apply the choosen completion */ + if (def_dlg->ret_value == B_ENTER) { + listbox_get_current (def_list, &curr, &curr_def); + if ( curr ) { + if ( edit_stack_iterator+1 < MAX_HISTORY_MOVETO ) { + g_free( edit_history_moveto[edit_stack_iterator].filename ); + edit_history_moveto[edit_stack_iterator].filename = g_strdup(edit->filename); + edit_history_moveto[edit_stack_iterator].line = edit->start_line + edit->curs_row + 1; + edit_stack_iterator++; + mc_log("%s:%i iterator=%i\n", curr_def->filename, curr_def->line, edit_stack_iterator); + g_free( edit_history_moveto[edit_stack_iterator].filename ); + edit_history_moveto[edit_stack_iterator].filename = g_strdup(curr_def->filename); + edit_history_moveto[edit_stack_iterator].line = curr_def->line; + edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename, + edit_history_moveto[edit_stack_iterator].line); + } + } + } + + /* clear definition hash */ + for ( int i = 0; i < MAX_DEFINITIONS; i++) { + g_free(def_hash[i].filename); + } + + /* destroy dialog before return */ + destroy_dlg (def_dlg); +} + + +void +edit_get_match_keyword_cmd (WEdit *edit) +{ + int word_len = 0, num_def = 0, max_len; + long word_start = 0; + unsigned char *bufpos; + char *match_expr; + struct def_hash_type def_hash[MAX_DEFINITIONS]; + + for ( int i = 0; i < MAX_DEFINITIONS; i++) { + def_hash[i].filename = NULL; + } + + /* search start of word to be completed */ + if (!edit_find_word_start (edit, &word_start, &word_len)) + return; + + /* prepare match expression */ + mc_log("edit_get_match_keyword_cmd\n"); + bufpos = &edit->buffers1[word_start >> S_EDIT_BUF_SIZE] + [word_start & M_EDIT_BUF_SIZE]; + match_expr = g_strdup_printf ("%.*s", word_len, bufpos); + + mc_log("%s \n", match_expr); + + set_def_hash("TAGS", match_expr, (struct def_hash_type *) &def_hash, &num_def); + max_len = 50; + word_len = 0; + if ( num_def > 0 ) { + edit_select_definition_dialog (edit, max_len, word_len, + (struct def_hash_type *) &def_hash, + num_def); + } + g_free (match_expr); +} diff --git a/edit/editcmddef.h b/edit/editcmddef.h index 213537619..3521d8b79 100644 --- a/edit/editcmddef.h +++ b/edit/editcmddef.h @@ -42,6 +42,8 @@ #define CK_Load 102 #define CK_New 103 #define CK_Save_As 104 +#define CK_Load_Prev_File 111 +#define CK_Load_Next_File 112 /* block commands */ #define CK_Mark 201 @@ -96,8 +98,9 @@ #define CK_Terminal 422 #define CK_Terminal_App 423 #define CK_ExtCmd 424 - #define CK_User_Menu 425 +#define CK_Find_Definition 426 + /* application control */ #define CK_Save_Desktop 451 #define CK_New_Window 452 diff --git a/edit/editkeys.c b/edit/editkeys.c index 2cc6add83..91306ca21 100644 --- a/edit/editkeys.c +++ b/edit/editkeys.c @@ -99,7 +99,7 @@ static const edit_key_map_type common_key_map[] = { { KEY_RIGHT, CK_Right }, { KEY_UP, CK_Up }, - { ALT ('\n'), CK_Return }, + { ALT ('\n'), CK_Find_Definition }, { ALT ('\t'), CK_Complete_Word }, { ALT ('l'), CK_Goto }, { ALT ('L'), CK_Goto }, @@ -108,6 +108,8 @@ static const edit_key_map_type common_key_map[] = { { ALT ('u'), CK_ExtCmd }, { ALT ('<'), CK_Beginning_Of_Text }, { ALT ('>'), CK_End_Of_Text }, + { ALT ('-'), CK_Load_Prev_File }, + { ALT ('='), CK_Load_Next_File }, { ALT (KEY_BACKSPACE), CK_Delete_Word_Left }, { XCTRL ('k'), CK_Delete_To_Line_End }, diff --git a/edit/etags.c b/edit/etags.c new file mode 100644 index 000000000..f0dac2b63 --- /dev/null +++ b/edit/etags.c @@ -0,0 +1,88 @@ +/*find . -type f -name "*.[ch]" | etags -l c --declarations - */ +#include +#include +#include +#include +#include +#include +#include "etags.h" + +long get_pos_from(char *str) +{ + static char buf[16]; + int i, j; + j = 0; + int len = strlen( str ); + for ( i = 0; i < len && i < 16; i++ ) { + char c = (char) str[i]; + if ( isdigit (c) ) { + buf[j++] = c; + buf[j] = '\0'; + } else { + return atol((char *)buf); + } + } + return 0; +} + +int set_def_hash(char *tagfile, char *match_func, struct def_hash_type *def_hash, int *num) +{ + FILE *f; + static char buf[4048]; + int len; + + f = fopen (tagfile, "r"); + int i; + if (!f) + return 1; + + len = strlen( match_func ); + int pos; + char *filename = NULL; + long line; + enum {start, in_filename, in_define} state=start; + + while (fgets (buf, sizeof (buf), f)) { + + switch ( state ) { + case start: + if ( buf[0] == 0x0C ) { + state = in_filename; + } + break; + case in_filename: + pos = strcspn(buf, ","); + if ( filename ) { + g_free(filename); + } + filename = malloc(pos + 2); + g_strlcpy ( filename, (char *)buf, pos + 1 ); + state = in_define; + break; + case in_define: + if ( buf[0] == 0x0C ) { + state = in_filename; + break; + } + /* check if the filename matches the define pos */ + if ( strstr ( buf, match_func ) ) { + int l = (int)strlen( buf ); + for ( i = 0; i < l; i++) { + if ( ( buf[i] == 0x7F || buf[i] == 0x01 ) && isdigit(buf[i+1]) ) { + line = get_pos_from(&buf[i+1]); + state = start; + if ( *num < MAX_DEFINITIONS ) { + def_hash[*num].filename_len = strlen(filename); + def_hash[*num].filename = g_strdup(filename); + def_hash[*num].line = line; + (*num)++; + } + } + } + } + break; + } + } + g_free(filename); + return 0; +} diff --git a/edit/etags.h b/edit/etags.h new file mode 100644 index 000000000..f2f8403a6 --- /dev/null +++ b/edit/etags.h @@ -0,0 +1,9 @@ +#define MAX_DEFINITIONS 50 + +struct def_hash_type { + int filename_len; + unsigned char *filename; + long line; +}; +long get_pos_from(char *str); +int set_def_hash(char *tagfile, char *match_func, struct def_hash_type *def_hash, int *num); diff --git a/src/main.c b/src/main.c index 4dcee7c9c..66a8d81ac 100644 --- a/src/main.c +++ b/src/main.c @@ -279,6 +279,11 @@ char *mc_home = NULL; char cmd_buf[512]; +#ifdef USE_INTERNAL_EDIT +int edit_stack_iterator = 0; +struct edit_stack_type edit_history_moveto[MAX_HISTORY_MOVETO]; +#endif + static void reload_panelized (WPanel *panel) { @@ -2135,6 +2140,13 @@ main (int argc, char *argv[]) vfs_init (); +#ifdef USE_INTERNAL_EDIT + for ( int i = 0; i < MAX_HISTORY_MOVETO; i++ ) { + edit_history_moveto[i].filename = NULL; + edit_history_moveto[i].line = -1; + } +#endif + #ifdef HAVE_SLANG SLtt_Ignore_Beep = 1; #endif @@ -2255,5 +2267,11 @@ main (int argc, char *argv[]) g_free (this_dir); g_free (other_dir); +#ifdef USE_INTERNAL_EDIT + for ( int i = 0; i < MAX_HISTORY_MOVETO; i++ ) { + g_free(edit_history_moveto[i].filename); + } +#endif + return 0; } diff --git a/src/main.h b/src/main.h index 1500548be..d858cb2ee 100644 --- a/src/main.h +++ b/src/main.h @@ -5,6 +5,10 @@ #include "panel.h" #include "widget.h" +#ifdef USE_INTERNAL_EDIT +#include "../edit/edit.h" +#endif + /* Toggling functions */ void toggle_fast_reload (void); void toggle_mix_all_files (void); @@ -38,6 +42,11 @@ extern int mou_auto_repeat; extern char *other_dir; extern int mouse_move_pages; +#ifdef USE_INTERNAL_EDIT +extern int edit_stack_iterator; +struct edit_stack_type edit_history_moveto[MAX_HISTORY_MOVETO]; +#endif + #ifdef HAVE_CHARSET extern int source_codepage; extern int display_codepage; From 351f42ac245bfe31e357ff00b0665890ae223d76 Mon Sep 17 00:00:00 2001 From: Ilia Maslakov Date: Thu, 26 Feb 2009 20:50:58 +0000 Subject: [PATCH 02/14] add recursive search file TAGS --- edit/editcmd.c | 33 ++++++++++++++++++++++++++++++--- edit/etags.c | 15 ++++++++------- edit/etags.h | 2 +- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/edit/editcmd.c b/edit/editcmd.c index a69cb89c3..02ce4a3b2 100644 --- a/edit/editcmd.c +++ b/edit/editcmd.c @@ -46,6 +46,7 @@ #include "editcmddef.h" #include "edit-widget.h" #include "etags.h" +#include "../src/panel.h" #include "../src/color.h" /* dialog_colors */ #include "../src/tty.h" /* LINES */ @@ -3095,7 +3096,7 @@ edit_select_definition_dialog (WEdit * edit, int max_len, int word_len, edit_history_moveto[edit_stack_iterator].filename = g_strdup(edit->filename); edit_history_moveto[edit_stack_iterator].line = edit->start_line + edit->curs_row + 1; edit_stack_iterator++; - mc_log("%s:%i iterator=%i\n", curr_def->filename, curr_def->line, edit_stack_iterator); +// mc_log("%s:%i iterator=%i\n", curr_def->filename, curr_def->line, edit_stack_iterator); g_free( edit_history_moveto[edit_stack_iterator].filename ); edit_history_moveto[edit_stack_iterator].filename = g_strdup(curr_def->filename); edit_history_moveto[edit_stack_iterator].line = curr_def->line; @@ -3120,8 +3121,14 @@ edit_get_match_keyword_cmd (WEdit *edit) { int word_len = 0, num_def = 0, max_len; long word_start = 0; + int len = 0; unsigned char *bufpos; char *match_expr; + char *path = NULL; + char *ptr = NULL; + char *tagfile = NULL; + FILE *f; + struct def_hash_type def_hash[MAX_DEFINITIONS]; for ( int i = 0; i < MAX_DEFINITIONS; i++) { @@ -3138,9 +3145,29 @@ edit_get_match_keyword_cmd (WEdit *edit) [word_start & M_EDIT_BUF_SIZE]; match_expr = g_strdup_printf ("%.*s", word_len, bufpos); - mc_log("%s \n", match_expr); + path = g_strdup_printf ("%s/", current_panel->cwd); + mc_log("%s\n", path); + len = strlen(path); + ptr = path + len; - set_def_hash("TAGS", match_expr, (struct def_hash_type *) &def_hash, &num_def); + while ( ptr != path ) { + if ( *ptr == '/' ) { + path[len] = '\0'; + g_free (tagfile); + tagfile = g_strdup_printf ("%s/TAGS", path); + mc_log("%s\n",tagfile); + f = fopen (tagfile, "r"); + if ( f ) { + break; + } + } + ptr--; + len--; + } + + set_def_hash(tagfile, path, match_expr, (struct def_hash_type *) &def_hash, &num_def); + g_free (path); + g_free (tagfile); max_len = 50; word_len = 0; if ( num_def > 0 ) { diff --git a/edit/etags.c b/edit/etags.c index f0dac2b63..56321729b 100644 --- a/edit/etags.c +++ b/edit/etags.c @@ -25,7 +25,7 @@ long get_pos_from(char *str) return 0; } -int set_def_hash(char *tagfile, char *match_func, struct def_hash_type *def_hash, int *num) +int set_def_hash(char *tagfile, char *start_path, char *match_func, struct def_hash_type *def_hash, int *num) { FILE *f; static char buf[4048]; @@ -35,12 +35,13 @@ int set_def_hash(char *tagfile, char *match_func, struct def_hash_type *def_hash int i; if (!f) return 1; - len = strlen( match_func ); int pos; + + char *fullpath = NULL; char *filename = NULL; long line; - enum {start, in_filename, in_define} state=start; + enum {start, in_filename, in_define} state = start; while (fgets (buf, sizeof (buf), f)) { @@ -52,9 +53,7 @@ int set_def_hash(char *tagfile, char *match_func, struct def_hash_type *def_hash break; case in_filename: pos = strcspn(buf, ","); - if ( filename ) { - g_free(filename); - } + g_free(filename); filename = malloc(pos + 2); g_strlcpy ( filename, (char *)buf, pos + 1 ); state = in_define; @@ -73,7 +72,9 @@ int set_def_hash(char *tagfile, char *match_func, struct def_hash_type *def_hash state = start; if ( *num < MAX_DEFINITIONS ) { def_hash[*num].filename_len = strlen(filename); - def_hash[*num].filename = g_strdup(filename); + fullpath = g_strdup_printf("%s/%s",start_path, filename); + def_hash[*num].filename = g_strdup(fullpath); + g_free(fullpath); def_hash[*num].line = line; (*num)++; } diff --git a/edit/etags.h b/edit/etags.h index f2f8403a6..8d25e784a 100644 --- a/edit/etags.h +++ b/edit/etags.h @@ -6,4 +6,4 @@ struct def_hash_type { long line; }; long get_pos_from(char *str); -int set_def_hash(char *tagfile, char *match_func, struct def_hash_type *def_hash, int *num); +int set_def_hash(char *tagfile, char *start_path, char *match_func, struct def_hash_type *def_hash, int *num); From 889233a7dd88eb61e48f4dc0618dd602bc136d24 Mon Sep 17 00:00:00 2001 From: Ilia Maslakov Date: Fri, 27 Feb 2009 21:31:30 +0000 Subject: [PATCH 03/14] add canonicalize_pathname for displayed files in list, replace get curren dir from panel->cwd to g_get_current_dir() --- edit/editcmd.c | 34 +++++++++++++++++++++------------- edit/etags.c | 1 + 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/edit/editcmd.c b/edit/editcmd.c index 02ce4a3b2..c059ed59b 100644 --- a/edit/editcmd.c +++ b/edit/editcmd.c @@ -3033,7 +3033,7 @@ edit_load_back_cmd (WEdit *edit) /* let the user select where function definition */ static void -edit_select_definition_dialog (WEdit * edit, int max_len, int word_len, +edit_select_definition_dialog (WEdit * edit, match_expr, int max_len, int word_len, struct def_hash_type *def_hash, int num_lines) { @@ -3067,7 +3067,7 @@ edit_select_definition_dialog (WEdit * edit, int max_len, int word_len, /* create the dialog */ def_dlg = create_dlg (start_y, start_x, def_dlg_h, def_dlg_w, - dialog_colors, NULL, "[Definitions]", NULL, + dialog_colors, NULL, "[Definitions]", match_expr, DLG_COMPACT); /* create the listbox */ @@ -3090,18 +3090,30 @@ edit_select_definition_dialog (WEdit * edit, int max_len, int word_len, /* apply the choosen completion */ if (def_dlg->ret_value == B_ENTER) { listbox_get_current (def_list, &curr, &curr_def); - if ( curr ) { + int do_moveto = 0; + if ( edit->modified ) { + if ( !edit_query_dialog2 + (_("Warning"), + _(" Current text was modified without a file save. \n" + " Continue discards these changes. "), _("C&ontinue"), + _("&Cancel"))) { + edit->force |= REDRAW_COMPLETELY; + do_moveto = 1; + } + } else { + do_moveto = 1; + } + if ( curr && do_moveto) { if ( edit_stack_iterator+1 < MAX_HISTORY_MOVETO ) { g_free( edit_history_moveto[edit_stack_iterator].filename ); edit_history_moveto[edit_stack_iterator].filename = g_strdup(edit->filename); edit_history_moveto[edit_stack_iterator].line = edit->start_line + edit->curs_row + 1; edit_stack_iterator++; -// mc_log("%s:%i iterator=%i\n", curr_def->filename, curr_def->line, edit_stack_iterator); g_free( edit_history_moveto[edit_stack_iterator].filename ); edit_history_moveto[edit_stack_iterator].filename = g_strdup(curr_def->filename); edit_history_moveto[edit_stack_iterator].line = curr_def->line; edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename, - edit_history_moveto[edit_stack_iterator].line); + edit_history_moveto[edit_stack_iterator].line); } } } @@ -3140,14 +3152,12 @@ edit_get_match_keyword_cmd (WEdit *edit) return; /* prepare match expression */ - mc_log("edit_get_match_keyword_cmd\n"); bufpos = &edit->buffers1[word_start >> S_EDIT_BUF_SIZE] [word_start & M_EDIT_BUF_SIZE]; match_expr = g_strdup_printf ("%.*s", word_len, bufpos); - path = g_strdup_printf ("%s/", current_panel->cwd); - mc_log("%s\n", path); - len = strlen(path); + path = g_strdup_printf ("%s/", g_get_current_dir()); + len = strlen (path); ptr = path + len; while ( ptr != path ) { @@ -3155,11 +3165,9 @@ edit_get_match_keyword_cmd (WEdit *edit) path[len] = '\0'; g_free (tagfile); tagfile = g_strdup_printf ("%s/TAGS", path); - mc_log("%s\n",tagfile); f = fopen (tagfile, "r"); - if ( f ) { + if ( f ) break; - } } ptr--; len--; @@ -3171,7 +3179,7 @@ edit_get_match_keyword_cmd (WEdit *edit) max_len = 50; word_len = 0; if ( num_def > 0 ) { - edit_select_definition_dialog (edit, max_len, word_len, + edit_select_definition_dialog (edit, match_expr, max_len, word_len, (struct def_hash_type *) &def_hash, num_def); } diff --git a/edit/etags.c b/edit/etags.c index 56321729b..9ac4feeca 100644 --- a/edit/etags.c +++ b/edit/etags.c @@ -73,6 +73,7 @@ int set_def_hash(char *tagfile, char *start_path, char *match_func, struct def_h if ( *num < MAX_DEFINITIONS ) { def_hash[*num].filename_len = strlen(filename); fullpath = g_strdup_printf("%s/%s",start_path, filename); + canonicalize_pathname (fullpath); def_hash[*num].filename = g_strdup(fullpath); g_free(fullpath); def_hash[*num].line = line; From ffca67e3cb578e38ba36432ec9a760a259e60a32 Mon Sep 17 00:00:00 2001 From: Ilia Maslakov Date: Fri, 27 Feb 2009 22:07:01 +0000 Subject: [PATCH 04/14] one word bug fix --- edit/editcmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edit/editcmd.c b/edit/editcmd.c index c059ed59b..ef968df24 100644 --- a/edit/editcmd.c +++ b/edit/editcmd.c @@ -3033,7 +3033,7 @@ edit_load_back_cmd (WEdit *edit) /* let the user select where function definition */ static void -edit_select_definition_dialog (WEdit * edit, match_expr, int max_len, int word_len, +edit_select_definition_dialog (WEdit * edit, char *match_expr, int max_len, int word_len, struct def_hash_type *def_hash, int num_lines) { From 8abf76df7c3140e85d2a83391c4ee54bd52a0924 Mon Sep 17 00:00:00 2001 From: Slava Zanko Date: Mon, 2 Mar 2009 16:43:22 +0200 Subject: [PATCH 05/14] edit/editcmd.c * changed searching algorithm of 'TAGS' file * changed #include "etags.h" to "../edit/etags.h" for building outside of sources tree edit/etags.c: * apply template from maint/template.c file * rename all functions with prefix etags_* * make function "etags_get_pos_from" in file-scope visibility edit/etags.h: * added logic block "#ifndef ... #define ... #endif" for correctly processing of header file * remove declaration of file-scope function etags_get_pos_from (ex. get_pos_from) --- edit/editcmd.c | 36 +++++++++++++++---------------- edit/etags.c | 58 +++++++++++++++++++++++++++++++++++++++++++++----- edit/etags.h | 9 ++++++-- 3 files changed, 77 insertions(+), 26 deletions(-) diff --git a/edit/editcmd.c b/edit/editcmd.c index ef968df24..4ea2cf7e7 100644 --- a/edit/editcmd.c +++ b/edit/editcmd.c @@ -45,7 +45,7 @@ #include "editlock.h" #include "editcmddef.h" #include "edit-widget.h" -#include "etags.h" +#include "../edit/etags.h" #include "../src/panel.h" #include "../src/color.h" /* dialog_colors */ @@ -3133,13 +3133,11 @@ edit_get_match_keyword_cmd (WEdit *edit) { int word_len = 0, num_def = 0, max_len; long word_start = 0; - int len = 0; unsigned char *bufpos; char *match_expr; char *path = NULL; char *ptr = NULL; char *tagfile = NULL; - FILE *f; struct def_hash_type def_hash[MAX_DEFINITIONS]; @@ -3157,25 +3155,25 @@ edit_get_match_keyword_cmd (WEdit *edit) match_expr = g_strdup_printf ("%.*s", word_len, bufpos); path = g_strdup_printf ("%s/", g_get_current_dir()); - len = strlen (path); - ptr = path + len; - while ( ptr != path ) { - if ( *ptr == '/' ) { - path[len] = '\0'; - g_free (tagfile); - tagfile = g_strdup_printf ("%s/TAGS", path); - f = fopen (tagfile, "r"); - if ( f ) - break; - } - ptr--; - len--; + ptr = path; + + /* Reursive search file 'TAGS' in parent dirs */ + do { + ptr = g_path_get_dirname (path); + g_free(path); path = ptr; + + tagfile = g_build_filename (path, "TAGS", NULL); + if ( exist_file (tagfile) ) + break; + } while (strcmp( path, G_DIR_SEPARATOR_S) != 0); + + if (tagfile){ + etags_set_def_hash(tagfile, path, match_expr, (struct def_hash_type *) &def_hash, &num_def); + g_free (tagfile); } - - set_def_hash(tagfile, path, match_expr, (struct def_hash_type *) &def_hash, &num_def); g_free (path); - g_free (tagfile); + max_len = 50; word_len = 0; if ( num_def > 0 ) { diff --git a/edit/etags.c b/edit/etags.c index 9ac4feeca..caca547a0 100644 --- a/edit/etags.c +++ b/edit/etags.c @@ -1,13 +1,58 @@ -/*find . -type f -name "*.[ch]" | etags -l c --declarations - */ +/* editor C-code navigation via tags. + make TAGS file via command: + $ find . -type f -name "*.[ch]" | etags -l c --declarations - + + or, if etags utility not installed: + $ ctags --languages=c -e -R -h '[ch]' + + Copyright (C) 2009 Free Software Foundation, Inc. + + Authors: + Ilia Maslakov , 2009 + Slava Zanko , 2009 + + + This file is part of the Midnight Commander. + + The Midnight Commander is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Midnight Commander 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. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. +*/ + +#include + #include #include #include #include #include #include -#include "etags.h" -long get_pos_from(char *str) +#include "../src/global.h" +#include "../edit/etags.h" + +/*** global variables **************************************************/ + +/*** file scope macro definitions **************************************/ + +/*** file scope type declarations **************************************/ + +/*** file scope variables **********************************************/ + +/*** file scope functions **********************************************/ + +static long etags_get_pos_from(char *str) { static char buf[16]; int i, j; @@ -25,7 +70,10 @@ long get_pos_from(char *str) return 0; } -int set_def_hash(char *tagfile, char *start_path, char *match_func, struct def_hash_type *def_hash, int *num) +/*** public functions **************************************************/ + + +int etags_set_def_hash(char *tagfile, char *start_path, char *match_func, struct def_hash_type *def_hash, int *num) { FILE *f; static char buf[4048]; @@ -68,7 +116,7 @@ int set_def_hash(char *tagfile, char *start_path, char *match_func, struct def_h int l = (int)strlen( buf ); for ( i = 0; i < l; i++) { if ( ( buf[i] == 0x7F || buf[i] == 0x01 ) && isdigit(buf[i+1]) ) { - line = get_pos_from(&buf[i+1]); + line = etags_get_pos_from(&buf[i+1]); state = start; if ( *num < MAX_DEFINITIONS ) { def_hash[*num].filename_len = strlen(filename); diff --git a/edit/etags.h b/edit/etags.h index 8d25e784a..b06ada96c 100644 --- a/edit/etags.h +++ b/edit/etags.h @@ -1,3 +1,6 @@ +#ifndef MC_EDIT_ETAGS_H +#define MC_EDIT_ETAGS_H 1 + #define MAX_DEFINITIONS 50 struct def_hash_type { @@ -5,5 +8,7 @@ struct def_hash_type { unsigned char *filename; long line; }; -long get_pos_from(char *str); -int set_def_hash(char *tagfile, char *start_path, char *match_func, struct def_hash_type *def_hash, int *num); + +int etags_set_def_hash(char *tagfile, char *start_path, char *match_func, struct def_hash_type *def_hash, int *num); + +#endif From 2a038f109a023cc5e814cc51c9696f581edca870 Mon Sep 17 00:00:00 2001 From: Ilia Maslakov Date: Wed, 4 Mar 2009 19:04:05 +0000 Subject: [PATCH 06/14] TAGS parser full reworked, add hungry search algorithm, change etags hash struct --- edit/etags.c | 142 ++++++++++++++++++++++++++++++++++----------------- edit/etags.h | 7 ++- 2 files changed, 101 insertions(+), 48 deletions(-) diff --git a/edit/etags.c b/edit/etags.c index caca547a0..d24690495 100644 --- a/edit/etags.c +++ b/edit/etags.c @@ -1,9 +1,9 @@ /* editor C-code navigation via tags. make TAGS file via command: - $ find . -type f -name "*.[ch]" | etags -l c --declarations - + $ find . -type f -name "*.[ch]" | etags -l c --declarations - or, if etags utility not installed: - $ ctags --languages=c -e -R -h '[ch]' + $ find . -type f -name "*.[ch]" | ctags -R --c-kinds=+p --fields=+iaS --extra=+q -e -L- Copyright (C) 2009 Free Software Foundation, Inc. @@ -42,53 +42,98 @@ #include "../src/global.h" #include "../edit/etags.h" -/*** global variables **************************************************/ - -/*** file scope macro definitions **************************************/ - -/*** file scope type declarations **************************************/ - -/*** file scope variables **********************************************/ - /*** file scope functions **********************************************/ -static long etags_get_pos_from(char *str) +int parse_define(char *buf, char **long_name, char **short_name, long *line) { - static char buf[16]; - int i, j; - j = 0; - int len = strlen( str ); - for ( i = 0; i < len && i < 16; i++ ) { - char c = (char) str[i]; - if ( isdigit (c) ) { - buf[j++] = c; - buf[j] = '\0'; - } else { - return atol((char *)buf); + enum {in_longname, in_shortname, in_line, finish} def_state = in_longname; + + static char longdef[LONG_DEF_LEN]; + static char shortdef[SHORT_DEF_LEN]; + static char linedef[LINE_DEF_LEN]; + int nlong = 0; + int nshort = 0; + int nline = 0; + char c = *buf; + + while ( !(c =='\0' || c =='\n') ) { + switch ( def_state ) { + case in_longname: + if ( c == 0x01 ) { + def_state = in_line; + } else if ( c == 0x7F ) { + def_state = in_shortname; + } else { + if ( nlong < LONG_DEF_LEN - 1 ) { + longdef[nlong++] = c; + } + } + break; + case in_shortname: + if ( isdigit(c) ) { + nshort = 0; + buf--; + def_state = in_line; + } else if ( c == 0x01 ) { + def_state = in_line; + } else { + if ( nshort < SHORT_DEF_LEN - 1 ) { + shortdef[nshort++] = c; + } + } + break; + case in_line: + if ( c == ',' ) { + def_state = finish; + } else if ( isdigit(c) ) { + if ( nline < LINE_DEF_LEN - 1 ) { + linedef[nline++] = c; + } + } + break; + case finish: + longdef[nlong] = '\0'; + shortdef[nshort] = '\0'; + linedef[nline] = '\0'; + *long_name = g_strdup (longdef); + *short_name = g_strdup (shortdef); + *line = atol (linedef); + return 1; + break; } + buf++; + c = *buf; } + *long_name = NULL; + *short_name = NULL; + *line = 0; return 0; } /*** public functions **************************************************/ - -int etags_set_def_hash(char *tagfile, char *start_path, char *match_func, struct def_hash_type *def_hash, int *num) +int etags_set_definition_hash(const char *tagfile, const char *start_path, + const char *match_func, + struct etags_hash_type *def_hash, + int *num) { FILE *f; - static char buf[4048]; - int len; + static char buf[1024]; + char *longname = NULL; + char *shortname = NULL; + long line; + + char *chekedstr = NULL; + + /* open file with positions */ f = fopen (tagfile, "r"); - int i; if (!f) return 1; - len = strlen( match_func ); - int pos; + int pos; char *fullpath = NULL; char *filename = NULL; - long line; enum {start, in_filename, in_define} state = start; while (fgets (buf, sizeof (buf), f)) { @@ -102,8 +147,8 @@ int etags_set_def_hash(char *tagfile, char *start_path, char *match_func, struct case in_filename: pos = strcspn(buf, ","); g_free(filename); - filename = malloc(pos + 2); - g_strlcpy ( filename, (char *)buf, pos + 1 ); + filename = malloc (pos + 2); + g_strlcpy(filename, (char *)buf, pos + 1); state = in_define; break; case in_define: @@ -112,22 +157,25 @@ int etags_set_def_hash(char *tagfile, char *start_path, char *match_func, struct break; } /* check if the filename matches the define pos */ - if ( strstr ( buf, match_func ) ) { - int l = (int)strlen( buf ); - for ( i = 0; i < l; i++) { - if ( ( buf[i] == 0x7F || buf[i] == 0x01 ) && isdigit(buf[i+1]) ) { - line = etags_get_pos_from(&buf[i+1]); - state = start; - if ( *num < MAX_DEFINITIONS ) { - def_hash[*num].filename_len = strlen(filename); - fullpath = g_strdup_printf("%s/%s",start_path, filename); - canonicalize_pathname (fullpath); - def_hash[*num].filename = g_strdup(fullpath); - g_free(fullpath); - def_hash[*num].line = line; - (*num)++; - } + chekedstr = strstr (buf, match_func); + if ( chekedstr ) { + parse_define (chekedstr, &longname, &shortname, &line); + if ( *num < MAX_DEFINITIONS - 1 ) { + def_hash[*num].filename_len = strlen (filename); + fullpath = g_strdup_printf("%s/%s",start_path, filename); + canonicalize_pathname (fullpath); + def_hash[*num].fullpath = g_strdup(fullpath); + g_free (fullpath); + def_hash[*num].filename = g_strdup (filename); + if ( shortname ) { + def_hash[*num].short_define = g_strdup (shortname); + } else { + def_hash[*num].short_define = g_strdup (longname); } + def_hash[*num].line = line; + g_free(shortname); + g_free(longname); + (*num)++; } } break; diff --git a/edit/etags.h b/edit/etags.h index b06ada96c..cc6041aa6 100644 --- a/edit/etags.h +++ b/edit/etags.h @@ -2,10 +2,15 @@ #define MC_EDIT_ETAGS_H 1 #define MAX_DEFINITIONS 50 +#define SHORT_DEF_LEN 30 +#define LONG_DEF_LEN 40 +#define LINE_DEF_LEN 16 -struct def_hash_type { +struct etags_hash_type { int filename_len; + unsigned char *fullpath; unsigned char *filename; + unsigned char *short_define; long line; }; From da66b3154bfba693750d0c10fbeef259e2640c77 Mon Sep 17 00:00:00 2001 From: Ilia Maslakov Date: Wed, 4 Mar 2009 19:42:56 +0000 Subject: [PATCH 07/14] small bug fix struct name --- edit/etags.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edit/etags.h b/edit/etags.h index cc6041aa6..c780eb044 100644 --- a/edit/etags.h +++ b/edit/etags.h @@ -14,6 +14,6 @@ struct etags_hash_type { long line; }; -int etags_set_def_hash(char *tagfile, char *start_path, char *match_func, struct def_hash_type *def_hash, int *num); +int etags_set_def_hash(char *tagfile, char *start_path, char *match_func, struct etags_hash_type *def_hash, int *num); #endif From 4be6c1c2c51e2005a26301ab4f0888ef6e58f431 Mon Sep 17 00:00:00 2001 From: Ilia Maslakov Date: Wed, 4 Mar 2009 20:10:55 +0000 Subject: [PATCH 08/14] some little bug fix --- edit/editcmd.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/edit/editcmd.c b/edit/editcmd.c index 4ea2cf7e7..28da936bb 100644 --- a/edit/editcmd.c +++ b/edit/editcmd.c @@ -3030,16 +3030,15 @@ edit_load_back_cmd (WEdit *edit) } } - /* let the user select where function definition */ static void edit_select_definition_dialog (WEdit * edit, char *match_expr, int max_len, int word_len, - struct def_hash_type *def_hash, int num_lines) + struct etags_hash_type *def_hash, int num_lines) { int start_x, start_y, offset, i; char *curr = NULL; - struct def_hash_type *curr_def; + struct etags_hash_type *curr_def; Dlg_head *def_dlg; WListbox *def_list; int def_dlg_h; /* dialog height */ @@ -3080,7 +3079,7 @@ edit_select_definition_dialog (WEdit * edit, char *match_expr, int max_len, int /* fill the listbox with the completions */ for (i = 0; i < num_lines; i++) { - label_def = g_strdup_printf ("%s:%i", def_hash[i].filename, def_hash[i].line); + label_def = g_strdup_printf ("%s>%s:%ld", def_hash[i].short_define, def_hash[i].filename, def_hash[i].line); listbox_add_item (def_list, LISTBOX_APPEND_AT_END, 0, label_def, &def_hash[i]); g_free(label_def); } @@ -3088,7 +3087,7 @@ edit_select_definition_dialog (WEdit * edit, char *match_expr, int max_len, int run_dlg (def_dlg); /* apply the choosen completion */ - if (def_dlg->ret_value == B_ENTER) { + if ( def_dlg->ret_value == B_ENTER ) { listbox_get_current (def_list, &curr, &curr_def); int do_moveto = 0; if ( edit->modified ) { @@ -3105,12 +3104,17 @@ edit_select_definition_dialog (WEdit * edit, char *match_expr, int max_len, int } if ( curr && do_moveto) { if ( edit_stack_iterator+1 < MAX_HISTORY_MOVETO ) { - g_free( edit_history_moveto[edit_stack_iterator].filename ); - edit_history_moveto[edit_stack_iterator].filename = g_strdup(edit->filename); - edit_history_moveto[edit_stack_iterator].line = edit->start_line + edit->curs_row + 1; + g_free (edit_history_moveto[edit_stack_iterator].filename); + if ( edit->dir ) { + edit_history_moveto[edit_stack_iterator].filename = g_strdup_printf ("%s/%s", edit->dir, edit->filename); + } else { + edit_history_moveto[edit_stack_iterator].filename = g_strdup (edit->filename); + } + edit_history_moveto[edit_stack_iterator].line = edit->start_line + + edit->curs_row + 1; edit_stack_iterator++; g_free( edit_history_moveto[edit_stack_iterator].filename ); - edit_history_moveto[edit_stack_iterator].filename = g_strdup(curr_def->filename); + edit_history_moveto[edit_stack_iterator].filename = g_strdup(curr_def->fullpath); edit_history_moveto[edit_stack_iterator].line = curr_def->line; edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename, edit_history_moveto[edit_stack_iterator].line); @@ -3131,7 +3135,9 @@ edit_select_definition_dialog (WEdit * edit, char *match_expr, int max_len, int void edit_get_match_keyword_cmd (WEdit *edit) { - int word_len = 0, num_def = 0, max_len; + int word_len = 0; + int num_def = 0; + int max_len = 0; long word_start = 0; unsigned char *bufpos; char *match_expr; @@ -3139,7 +3145,7 @@ edit_get_match_keyword_cmd (WEdit *edit) char *ptr = NULL; char *tagfile = NULL; - struct def_hash_type def_hash[MAX_DEFINITIONS]; + struct etags_hash_type def_hash[MAX_DEFINITIONS]; for ( int i = 0; i < MAX_DEFINITIONS; i++) { def_hash[i].filename = NULL; @@ -3169,7 +3175,7 @@ edit_get_match_keyword_cmd (WEdit *edit) } while (strcmp( path, G_DIR_SEPARATOR_S) != 0); if (tagfile){ - etags_set_def_hash(tagfile, path, match_expr, (struct def_hash_type *) &def_hash, &num_def); + etags_set_definition_hash(tagfile, path, match_expr, (struct etags_hash_type *) &def_hash, &num_def); g_free (tagfile); } g_free (path); @@ -3178,7 +3184,7 @@ edit_get_match_keyword_cmd (WEdit *edit) word_len = 0; if ( num_def > 0 ) { edit_select_definition_dialog (edit, match_expr, max_len, word_len, - (struct def_hash_type *) &def_hash, + (struct etags_hash_type *) &def_hash, num_def); } g_free (match_expr); From 474d22d6c98f5f1388e17cf0056b2efd61885f21 Mon Sep 17 00:00:00 2001 From: Ilia Maslakov Date: Wed, 4 Mar 2009 20:22:50 +0000 Subject: [PATCH 09/14] change width listbox, change output format --- edit/editcmd.c | 4 ++-- edit/etags.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/edit/editcmd.c b/edit/editcmd.c index 28da936bb..53c1989e0 100644 --- a/edit/editcmd.c +++ b/edit/editcmd.c @@ -3079,7 +3079,7 @@ edit_select_definition_dialog (WEdit * edit, char *match_expr, int max_len, int /* fill the listbox with the completions */ for (i = 0; i < num_lines; i++) { - label_def = g_strdup_printf ("%s>%s:%ld", def_hash[i].short_define, def_hash[i].filename, def_hash[i].line); + label_def = g_strdup_printf ("%s -> %s:%ld", def_hash[i].short_define, def_hash[i].filename, def_hash[i].line); listbox_add_item (def_list, LISTBOX_APPEND_AT_END, 0, label_def, &def_hash[i]); g_free(label_def); } @@ -3180,7 +3180,7 @@ edit_get_match_keyword_cmd (WEdit *edit) } g_free (path); - max_len = 50; + max_len = 60; word_len = 0; if ( num_def > 0 ) { edit_select_definition_dialog (edit, match_expr, max_len, word_len, diff --git a/edit/etags.h b/edit/etags.h index c780eb044..ae3c3eba1 100644 --- a/edit/etags.h +++ b/edit/etags.h @@ -1,7 +1,7 @@ #ifndef MC_EDIT_ETAGS_H #define MC_EDIT_ETAGS_H 1 -#define MAX_DEFINITIONS 50 +#define MAX_DEFINITIONS 60 #define SHORT_DEF_LEN 30 #define LONG_DEF_LEN 40 #define LINE_DEF_LEN 16 From 00567b61b29c947440fad15f1c28c324e3d0ce5d Mon Sep 17 00:00:00 2001 From: Slava Zanko Date: Thu, 5 Mar 2009 12:27:45 +0200 Subject: [PATCH 10/14] etags: make new type 'etags_hash_t' --- edit/editcmd.c | 10 +++++----- edit/etags.c | 2 +- edit/etags.h | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/edit/editcmd.c b/edit/editcmd.c index 53c1989e0..023e0d00a 100644 --- a/edit/editcmd.c +++ b/edit/editcmd.c @@ -3033,12 +3033,12 @@ edit_load_back_cmd (WEdit *edit) /* let the user select where function definition */ static void edit_select_definition_dialog (WEdit * edit, char *match_expr, int max_len, int word_len, - struct etags_hash_type *def_hash, int num_lines) + etags_hash_t *def_hash, int num_lines) { int start_x, start_y, offset, i; char *curr = NULL; - struct etags_hash_type *curr_def; + etags_hash_t *curr_def; Dlg_head *def_dlg; WListbox *def_list; int def_dlg_h; /* dialog height */ @@ -3145,7 +3145,7 @@ edit_get_match_keyword_cmd (WEdit *edit) char *ptr = NULL; char *tagfile = NULL; - struct etags_hash_type def_hash[MAX_DEFINITIONS]; + etags_hash_t def_hash[MAX_DEFINITIONS]; for ( int i = 0; i < MAX_DEFINITIONS; i++) { def_hash[i].filename = NULL; @@ -3175,7 +3175,7 @@ edit_get_match_keyword_cmd (WEdit *edit) } while (strcmp( path, G_DIR_SEPARATOR_S) != 0); if (tagfile){ - etags_set_definition_hash(tagfile, path, match_expr, (struct etags_hash_type *) &def_hash, &num_def); + etags_set_definition_hash(tagfile, path, match_expr, (etags_hash_t *) &def_hash, &num_def); g_free (tagfile); } g_free (path); @@ -3184,7 +3184,7 @@ edit_get_match_keyword_cmd (WEdit *edit) word_len = 0; if ( num_def > 0 ) { edit_select_definition_dialog (edit, match_expr, max_len, word_len, - (struct etags_hash_type *) &def_hash, + (etags_hash_t *) &def_hash, num_def); } g_free (match_expr); diff --git a/edit/etags.c b/edit/etags.c index d24690495..4bbea0d86 100644 --- a/edit/etags.c +++ b/edit/etags.c @@ -114,7 +114,7 @@ int parse_define(char *buf, char **long_name, char **short_name, long *line) int etags_set_definition_hash(const char *tagfile, const char *start_path, const char *match_func, - struct etags_hash_type *def_hash, + etags_hash_t *def_hash, int *num) { FILE *f; diff --git a/edit/etags.h b/edit/etags.h index ae3c3eba1..62a128294 100644 --- a/edit/etags.h +++ b/edit/etags.h @@ -6,14 +6,14 @@ #define LONG_DEF_LEN 40 #define LINE_DEF_LEN 16 -struct etags_hash_type { +typedef struct etags_hash_struct { int filename_len; unsigned char *fullpath; unsigned char *filename; unsigned char *short_define; long line; -}; +} etags_hash_t; -int etags_set_def_hash(char *tagfile, char *start_path, char *match_func, struct etags_hash_type *def_hash, int *num); +int etags_set_def_hash(char *tagfile, char *start_path, char *match_func, etags_hash_t *def_hash, int *num); #endif From 6c39432c9802903223ed0e50b2cb822c9ba5ba6b Mon Sep 17 00:00:00 2001 From: Slava Zanko Date: Thu, 5 Mar 2009 12:48:47 +0200 Subject: [PATCH 11/14] edit/etags.c: Use function 'g_build_filename' instread of 'g_strdup_printf' for making path to file --- edit/etags.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edit/etags.c b/edit/etags.c index 4bbea0d86..babc2f23b 100644 --- a/edit/etags.c +++ b/edit/etags.c @@ -162,7 +162,7 @@ int etags_set_definition_hash(const char *tagfile, const char *start_path, parse_define (chekedstr, &longname, &shortname, &line); if ( *num < MAX_DEFINITIONS - 1 ) { def_hash[*num].filename_len = strlen (filename); - fullpath = g_strdup_printf("%s/%s",start_path, filename); + fullpath = g_build_filename (start_path, filename, NULL); canonicalize_pathname (fullpath); def_hash[*num].fullpath = g_strdup(fullpath); g_free (fullpath); From f3dcf1b3aa515c473a808243455ae0184f38c238 Mon Sep 17 00:00:00 2001 From: Ilia Maslakov Date: Fri, 6 Mar 2009 15:28:54 +0000 Subject: [PATCH 12/14] replace malloc to g_malloc. fix some leak (thx andrew_b) define TAGS_NAME, MAX_WIDTH_DEF_DIALOG vars --- edit/editcmd.c | 18 +++++++++--------- edit/etags.c | 45 ++++++++++++++++++++++----------------------- edit/etags.h | 14 ++++++++++---- 3 files changed, 41 insertions(+), 36 deletions(-) diff --git a/edit/editcmd.c b/edit/editcmd.c index 023e0d00a..d3f8ecf03 100644 --- a/edit/editcmd.c +++ b/edit/editcmd.c @@ -3088,7 +3088,7 @@ edit_select_definition_dialog (WEdit * edit, char *match_expr, int max_len, int /* apply the choosen completion */ if ( def_dlg->ret_value == B_ENTER ) { - listbox_get_current (def_list, &curr, &curr_def); + listbox_get_current (def_list, &curr, (etags_hash_t *) &curr_def); int do_moveto = 0; if ( edit->modified ) { if ( !edit_query_dialog2 @@ -3160,27 +3160,27 @@ edit_get_match_keyword_cmd (WEdit *edit) [word_start & M_EDIT_BUF_SIZE]; match_expr = g_strdup_printf ("%.*s", word_len, bufpos); - path = g_strdup_printf ("%s/", g_get_current_dir()); + ptr = g_get_current_dir (); + path = g_strconcat (ptr, G_DIR_SEPARATOR_S, (char *) NULL); + g_free (ptr); - ptr = path; - - /* Reursive search file 'TAGS' in parent dirs */ + /* Recursive search file 'TAGS' in parent dirs */ do { ptr = g_path_get_dirname (path); g_free(path); path = ptr; - - tagfile = g_build_filename (path, "TAGS", NULL); + g_free (tagfile); + tagfile = g_build_filename (path, TAGS_NAME, (char *) NULL); if ( exist_file (tagfile) ) break; } while (strcmp( path, G_DIR_SEPARATOR_S) != 0); if (tagfile){ - etags_set_definition_hash(tagfile, path, match_expr, (etags_hash_t *) &def_hash, &num_def); + num_def = etags_set_definition_hash(tagfile, path, match_expr, (etags_hash_t *) &def_hash); g_free (tagfile); } g_free (path); - max_len = 60; + max_len = MAX_WIDTH_DEF_DIALOG; word_len = 0; if ( num_def > 0 ) { edit_select_definition_dialog (edit, match_expr, max_len, word_len, diff --git a/edit/etags.c b/edit/etags.c index babc2f23b..4b16013db 100644 --- a/edit/etags.c +++ b/edit/etags.c @@ -3,7 +3,7 @@ $ find . -type f -name "*.[ch]" | etags -l c --declarations - or, if etags utility not installed: - $ find . -type f -name "*.[ch]" | ctags -R --c-kinds=+p --fields=+iaS --extra=+q -e -L- + $ find . -type f -name "*.[ch]" | ctags --c-kinds=+p --fields=+iaS --extra=+q -e -L- Copyright (C) 2009 Free Software Foundation, Inc. @@ -36,15 +36,15 @@ #include #include #include -#include #include #include "../src/global.h" +#include "../src/util.h" /* canonicalize_pathname() */ #include "../edit/etags.h" /*** file scope functions **********************************************/ -int parse_define(char *buf, char **long_name, char **short_name, long *line) +gboolean parse_define(char *buf, char **long_name, char **short_name, long *line) { enum {in_longname, in_shortname, in_line, finish} def_state = in_longname; @@ -98,7 +98,7 @@ int parse_define(char *buf, char **long_name, char **short_name, long *line) *long_name = g_strdup (longdef); *short_name = g_strdup (shortdef); *line = atol (linedef); - return 1; + return TRUE; break; } buf++; @@ -107,18 +107,17 @@ int parse_define(char *buf, char **long_name, char **short_name, long *line) *long_name = NULL; *short_name = NULL; *line = 0; - return 0; + return FALSE; } /*** public functions **************************************************/ int etags_set_definition_hash(const char *tagfile, const char *start_path, const char *match_func, - etags_hash_t *def_hash, - int *num) + etags_hash_t *def_hash) { FILE *f; - static char buf[1024]; + static char buf[BUF_LARGE]; char *longname = NULL; char *shortname = NULL; @@ -126,13 +125,14 @@ int etags_set_definition_hash(const char *tagfile, const char *start_path, char *chekedstr = NULL; + int num = 0; /* returned value */ + /* open file with positions */ f = fopen (tagfile, "r"); if (!f) - return 1; + return 0; int pos; - char *fullpath = NULL; char *filename = NULL; enum {start, in_filename, in_define} state = start; @@ -147,7 +147,7 @@ int etags_set_definition_hash(const char *tagfile, const char *start_path, case in_filename: pos = strcspn(buf, ","); g_free(filename); - filename = malloc (pos + 2); + filename = g_malloc (pos + 2); g_strlcpy(filename, (char *)buf, pos + 1); state = in_define; break; @@ -160,27 +160,26 @@ int etags_set_definition_hash(const char *tagfile, const char *start_path, chekedstr = strstr (buf, match_func); if ( chekedstr ) { parse_define (chekedstr, &longname, &shortname, &line); - if ( *num < MAX_DEFINITIONS - 1 ) { - def_hash[*num].filename_len = strlen (filename); - fullpath = g_build_filename (start_path, filename, NULL); - canonicalize_pathname (fullpath); - def_hash[*num].fullpath = g_strdup(fullpath); - g_free (fullpath); - def_hash[*num].filename = g_strdup (filename); + if ( num < MAX_DEFINITIONS - 1 ) { + def_hash[num].filename_len = strlen (filename); + def_hash[num].fullpath = g_build_filename (start_path, filename, (char *) NULL); + canonicalize_pathname (def_hash[num].fullpath); + def_hash[num].filename = g_strdup (filename); if ( shortname ) { - def_hash[*num].short_define = g_strdup (shortname); + def_hash[num].short_define = g_strdup (shortname); } else { - def_hash[*num].short_define = g_strdup (longname); + def_hash[num].short_define = g_strdup (longname); } - def_hash[*num].line = line; + def_hash[num].line = line; g_free(shortname); g_free(longname); - (*num)++; + num++; } } break; } } + g_free(filename); - return 0; + return num; } diff --git a/edit/etags.h b/edit/etags.h index 62a128294..9e60b5bae 100644 --- a/edit/etags.h +++ b/edit/etags.h @@ -1,19 +1,25 @@ #ifndef MC_EDIT_ETAGS_H #define MC_EDIT_ETAGS_H 1 -#define MAX_DEFINITIONS 60 +#include /* size_t */ +#include "../src/global.h" /* include */ + +#define MAX_WIDTH_DEF_DIALOG 60 /* max width def dialog */ +#define MAX_DEFINITIONS 60 /* count found entries show */ #define SHORT_DEF_LEN 30 #define LONG_DEF_LEN 40 #define LINE_DEF_LEN 16 +#define TAGS_NAME "TAGS" typedef struct etags_hash_struct { - int filename_len; + size_t filename_len; unsigned char *fullpath; unsigned char *filename; unsigned char *short_define; long line; } etags_hash_t; -int etags_set_def_hash(char *tagfile, char *start_path, char *match_func, etags_hash_t *def_hash, int *num); +int etags_set_definition_hash (const char *tagfile, const char *start_path, + const char *match_func, etags_hash_t *def_hash); -#endif +#endif /* MC_EDIT_ETAGS_H */ From 70be4fbf7be2f2c8fab1a9c0ef9cbb9eebf88511 Mon Sep 17 00:00:00 2001 From: Ilia Maslakov Date: Tue, 10 Mar 2009 20:08:30 +0000 Subject: [PATCH 13/14] fix err in Makefile.am. Change etats.h to etags.h --- edit/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edit/Makefile.am b/edit/Makefile.am index ce828716a..a658fabee 100644 --- a/edit/Makefile.am +++ b/edit/Makefile.am @@ -10,6 +10,6 @@ libedit_a_SOURCES = \ bookmark.c edit.c editcmd.c editwidget.c editdraw.c editkeys.c \ editmenu.c editoptions.c editcmddef.h edit.h edit-widget.h \ editlock.c editlock.h syntax.c usermap.h usermap.c wordproc.c \ - choosesyntax.c etags.c etats.h + choosesyntax.c etags.c etags.h EXTRA_DIST = ChangeLog From e7b82fe9f311dc8ee9c4a9a64b96f0f7faffe7c5 Mon Sep 17 00:00:00 2001 From: Ilia Maslakov Date: Tue, 10 Mar 2009 20:11:51 +0000 Subject: [PATCH 14/14] add static in parse_define --- edit/etags.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edit/etags.c b/edit/etags.c index 4b16013db..525848c7c 100644 --- a/edit/etags.c +++ b/edit/etags.c @@ -44,7 +44,7 @@ /*** file scope functions **********************************************/ -gboolean parse_define(char *buf, char **long_name, char **short_name, long *line) +static gboolean parse_define(char *buf, char **long_name, char **short_name, long *line) { enum {in_longname, in_shortname, in_line, finish} def_state = in_longname;