Ticket #3530: mc-3530-v0.patch

File mc-3530-v0.patch, 16.8 KB (added by egmont, 5 years ago)

Proof of concept fix

  • src/filemanager/cmd.c

    diff --git a/src/filemanager/cmd.c b/src/filemanager/cmd.c
    index 557964e..fabafc1 100644
    a b set_basic_panel_listing_to (int panel_index, int listing_mode) 
    541541 
    542542gboolean 
    543543view_file_at_line (const vfs_path_t * filename_vpath, gboolean plain_view, gboolean internal, 
    544                    long start_line) 
     544                   long start_line, off_t search_start, off_t search_end) 
    545545{ 
    546546    gboolean ret = TRUE; 
    547547 
    view_file_at_line (const vfs_path_t * filename_vpath, gboolean plain_view, gbool 
    564564        mcview_default_nroff_flag = 0; 
    565565        mcview_default_magic_flag = 0; 
    566566 
    567         ret = mcview_viewer (NULL, filename_vpath, start_line); 
     567        ret = mcview_viewer (NULL, filename_vpath, start_line, search_start, search_end); 
    568568 
    569569        if (changed_hex_mode && !mcview_altered_hex_mode) 
    570570            mcview_default_hex_mode = 1; 
    view_file_at_line (const vfs_path_t * filename_vpath, gboolean plain_view, gbool 
    587587        ret = (regex_command (filename_vpath, view_entry) == 0); 
    588588        if (ret) 
    589589        { 
    590             ret = mcview_viewer (NULL, filename_vpath, start_line); 
     590            ret = mcview_viewer (NULL, filename_vpath, start_line, search_start, search_end); 
    591591            dialog_switch_process_pending (); 
    592592        } 
    593593    } 
    view_file_at_line (const vfs_path_t * filename_vpath, gboolean plain_view, gbool 
    623623gboolean 
    624624view_file (const vfs_path_t * filename_vpath, gboolean plain_view, gboolean internal) 
    625625{ 
    626     return view_file_at_line (filename_vpath, plain_view, internal, 0); 
     626    return view_file_at_line (filename_vpath, plain_view, internal, 0, 0, 0); 
    627627} 
    628628 
    629629 
    view_filtered_cmd (void) 
    687687 
    688688    if (command != NULL) 
    689689    { 
    690         mcview_viewer (command, NULL, 0); 
     690        mcview_viewer (command, NULL, 0, 0, 0); 
    691691        g_free (command); 
    692692        dialog_switch_process_pending (); 
    693693    } 
  • src/filemanager/cmd.h

    diff --git a/src/filemanager/cmd.h b/src/filemanager/cmd.h
    index 892f1ce..33f713d 100644
    a b void smart_dirsize_cmd (void); 
    4444void single_dirsize_cmd (void); 
    4545void dirsizes_cmd (void); 
    4646gboolean view_file_at_line (const vfs_path_t * filename_vpath, gboolean plain_view, 
    47                             gboolean internal, long start_line); 
     47                            gboolean internal, long start_line, off_t search_start, off_t search_end); 
    4848gboolean view_file (const vfs_path_t * filename_vpath, gboolean normal, gboolean internal); 
    4949void view_cmd (void); 
    5050void view_file_cmd (void); 
  • src/filemanager/ext.c

    diff --git a/src/filemanager/ext.c b/src/filemanager/ext.c
    index 2fa9ae5..b8f7da3 100644
    a b exec_extension_view (void *target, char *cmd, const vfs_path_t * filename_vpath, 
    364364        changed_nroff_flag = 1; 
    365365 
    366366    if (target == NULL) 
    367         mcview_viewer (cmd, filename_vpath, start_line); 
     367        mcview_viewer (cmd, filename_vpath, start_line, 0, 0); 
    368368    else 
    369         mcview_load ((mcview_t *) target, cmd, vfs_path_as_str (filename_vpath), start_line); 
     369        mcview_load ((mcview_t *) target, cmd, vfs_path_as_str (filename_vpath), start_line, 0, 0); 
    370370 
    371371    if (changed_hex_mode && !mcview_altered_hex_mode) 
    372372        mcview_default_hex_mode = def_hex_mode; 
  • src/filemanager/find.c

    diff --git a/src/filemanager/find.c b/src/filemanager/find.c
    index 1b829b3..9eb2b37 100644
    a b typedef struct 
    111111    char *ignore_dirs; 
    112112} find_file_options_t; 
    113113 
     114typedef struct 
     115{ 
     116    char *dir; 
     117    gsize start; 
     118    gsize end; 
     119} find_match_location_t; 
     120 
    114121/*** file scope variables ************************************************************************/ 
    115122 
    116123/* button callbacks */ 
    static struct timeval last_refresh; 
    157164static gboolean resuming; 
    158165static int last_line; 
    159166static int last_pos; 
     167static off_t last_off; 
     168static int last_i; 
    160169 
    161170static size_t ignore_count = 0; 
    162171 
    found_num_update (void) 
    364373/* --------------------------------------------------------------------------------------------- */ 
    365374 
    366375static void 
    367 get_list_info (char **file, char **dir) 
     376get_list_info (char **file, char **dir, gsize *start, gsize *end) 
    368377{ 
    369     listbox_get_current (find_list, file, (void **) dir); 
     378    find_match_location_t *location = NULL; 
     379    listbox_get_current (find_list, file, (void **) &location); 
     380    if (location != NULL) 
     381    { 
     382      *dir = location->dir; 
     383      *start = location->start; 
     384      *end = location->end; 
     385    } 
     386    else 
     387    { 
     388      *dir = NULL; 
     389    } 
    370390} 
    371391 
    372392/* --------------------------------------------------------------------------------------------- */ 
    clear_stack (void) 
    825845/* --------------------------------------------------------------------------------------------- */ 
    826846 
    827847static void 
    828 insert_file (const char *dir, const char *file) 
     848insert_file (const char *dir, const char *file, gsize start, gsize end) 
    829849{ 
    830850    char *tmp_name = NULL; 
    831851    static char *dirname = NULL; 
     852    find_match_location_t *location; 
    832853 
    833854    while (IS_PATH_SEP (dir[0]) && IS_PATH_SEP (dir[1])) 
    834855        dir++; 
    insert_file (const char *dir, const char *file) 
    849870    } 
    850871 
    851872    tmp_name = g_strdup_printf ("    %s", file); 
    852     add_to_list (tmp_name, dirname); 
     873    location = g_malloc (sizeof location);  // TODO FIXME how to free this? 
     874    location->dir = dirname; 
     875    location->start = start; 
     876    location->end = end; 
     877    add_to_list (tmp_name, location); 
    853878    g_free (tmp_name); 
    854879} 
    855880 
    856881/* --------------------------------------------------------------------------------------------- */ 
    857882 
    858883static void 
    859 find_add_match (const char *dir, const char *file) 
     884find_add_match (const char *dir, const char *file, gsize start, gsize end) 
    860885{ 
    861     insert_file (dir, file); 
     886    insert_file (dir, file, start, end); 
    862887 
    863888    /* Don't scroll */ 
    864889    if (matches == 0) 
    search_content (WDialog * h, const char *directory, const char *filename) 
    967992        int line = 1; 
    968993        int pos = 0; 
    969994        int n_read = 0; 
     995        off_t off = 0;          /* file_fd's offset corresponding to strbuf[0] */ 
    970996        gboolean found = FALSE; 
    971997        gsize found_len; 
     998        gsize found_start; 
    972999        char result[BUF_MEDIUM]; 
    9731000        char *strbuf = NULL;    /* buffer for fetched string */ 
    9741001        int strbuf_size = 0; 
     1002        int i = -1;             /* compensate for a newline we'll add when we first enter the loop */ 
    9751003 
    9761004        if (resuming) 
    9771005        { 
    search_content (WDialog * h, const char *directory, const char *filename) 
    9791007            resuming = FALSE; 
    9801008            line = last_line; 
    9811009            pos = last_pos; 
     1010            off = last_off; 
     1011            i = last_i; 
    9821012        } 
    9831013 
    9841014        while (!ret_val) 
    9851015        { 
    9861016            char ch = '\0'; 
    987             int i = 0; 
     1017            off += i + 1;       /* the previous line, plus a newline character */ 
     1018            i = 0; 
    9881019 
    9891020            /* read to buffer and get line from there */ 
    9901021            while (TRUE) 
    search_content (WDialog * h, const char *directory, const char *filename) 
    10021033                { 
    10031034                    /* skip possible leading zero(s) */ 
    10041035                    if (i == 0) 
     1036                    { 
     1037                        off++; 
    10051038                        continue; 
     1039                    } 
    10061040                    break; 
    10071041                } 
    10081042 
    search_content (WDialog * h, const char *directory, const char *filename) 
    10451079                } 
    10461080 
    10471081                g_snprintf (result, sizeof (result), "%d:%s", line, filename); 
    1048                 find_add_match (directory, result); 
     1082                found_start = off + search_content_handle->normal_offset + 1; /* off by one ouch: ticket 3280 */ 
     1083                find_add_match (directory, result, found_start, found_start + found_len); 
    10491084                found = TRUE; 
    10501085            } 
    10511086 
    search_content (WDialog * h, const char *directory, const char *filename) 
    10731108                    resuming = TRUE; 
    10741109                    last_line = line; 
    10751110                    last_pos = pos; 
     1111                    last_off = off; 
     1112                    last_i = i; 
    10761113                    ret_val = TRUE; 
    10771114                    break; 
    10781115                default: 
    do_search (WDialog * h) 
    13011338            if (search_ok) 
    13021339            { 
    13031340                if (content_pattern == NULL) 
    1304                     find_add_match (directory, dp->d_name); 
     1341                    find_add_match (directory, dp->d_name, 0, 0); 
    13051342                else if (search_content (h, directory, dp->d_name)) 
    13061343                    return 1; 
    13071344            } 
    init_find_vars (void) 
    13361373/* --------------------------------------------------------------------------------------------- */ 
    13371374 
    13381375static void 
    1339 find_do_view_edit (gboolean unparsed_view, gboolean edit, char *dir, char *file) 
     1376find_do_view_edit (gboolean unparsed_view, gboolean edit, char *dir, char *file, off_t search_start, off_t search_end) 
    13401377{ 
    13411378    char *fullname = NULL; 
    13421379    const char *filename = NULL; 
    find_do_view_edit (gboolean unparsed_view, gboolean edit, char *dir, char *file) 
    13581395    if (edit) 
    13591396        edit_file_at_line (fullname_vpath, use_internal_edit != 0, line); 
    13601397    else 
    1361         view_file_at_line (fullname_vpath, unparsed_view, use_internal_view != 0, line); 
     1398        view_file_at_line (fullname_vpath, unparsed_view, use_internal_view != 0, line, search_start, search_end); 
    13621399    vfs_path_free (fullname_vpath); 
    13631400    g_free (fullname); 
    13641401} 
    find_do_view_edit (gboolean unparsed_view, gboolean edit, char *dir, char *file) 
    13681405static cb_ret_t 
    13691406view_edit_currently_selected_file (gboolean unparsed_view, gboolean edit) 
    13701407{ 
    1371     char *dir = NULL; 
    13721408    char *text = NULL; 
     1409    find_match_location_t *location; 
    13731410 
    1374     listbox_get_current (find_list, &text, (void **) &dir); 
     1411    listbox_get_current (find_list, &text, (void **) &location); 
    13751412 
    1376     if ((text == NULL) || (dir == NULL)) 
     1413    if ((text == NULL) || (location == NULL) || (location->dir == NULL)) 
    13771414        return MSG_NOT_HANDLED; 
    13781415 
    1379     find_do_view_edit (unparsed_view, edit, dir, text); 
     1416    find_do_view_edit (unparsed_view, edit, location->dir, text, location->start, location->end); 
    13801417    return MSG_HANDLED; 
    13811418} 
    13821419 
    do_find (const char *start_dir, ssize_t start_dir_len, const char *ignore_dirs, 
    16281665{ 
    16291666    int return_value = 0; 
    16301667    char *dir_tmp = NULL, *file_tmp = NULL; 
     1668    gsize start, len; 
    16311669 
    16321670    setup_gui (); 
    16331671 
    do_find (const char *start_dir, ssize_t start_dir_len, const char *ignore_dirs, 
    16471685    /* Clear variables */ 
    16481686    init_find_vars (); 
    16491687 
    1650     get_list_info (&file_tmp, &dir_tmp); 
     1688    get_list_info (&file_tmp, &dir_tmp, &start, &len); 
    16511689 
    16521690    if (dir_tmp) 
    16531691        *dirname = g_strdup (dir_tmp); 
    do_find (const char *start_dir, ssize_t start_dir_len, const char *ignore_dirs, 
    16701708        { 
    16711709            const char *lc_filename = NULL; 
    16721710            WLEntry *le = LENTRY (entry->data); 
     1711            find_match_location_t *location = le->data; 
    16731712            char *p; 
    16741713 
    1675             if ((le->text == NULL) || (le->data == NULL)) 
     1714            if ((le->text == NULL) || (location == NULL) || (location->dir == NULL)) 
    16761715                continue; 
    16771716 
    16781717            if (content_pattern != NULL) 
    do_find (const char *start_dir, ssize_t start_dir_len, const char *ignore_dirs, 
    16801719            else 
    16811720                lc_filename = le->text + 4; 
    16821721 
    1683             name = mc_build_filename (le->data, lc_filename, (char *) NULL); 
     1722            name = mc_build_filename (location->dir, lc_filename, (char *) NULL); 
    16841723            /* skip initial start dir */ 
    16851724            if (start_dir_len < 0) 
    16861725                p = name; 
  • src/filemanager/layout.c

    diff --git a/src/filemanager/layout.c b/src/filemanager/layout.c
    index adc068e..bf6c26a 100644
    a b set_display_type (int num, panel_view_mode_t type) 
    10201020        else 
    10211021            file_name = ""; 
    10221022 
    1023         mcview_load ((struct mcview_struct *) new_widget, 0, file_name, 0); 
     1023        mcview_load ((struct mcview_struct *) new_widget, 0, file_name, 0, 0, 0); 
    10241024        break; 
    10251025 
    10261026    default: 
  • src/filemanager/usermenu.c

    diff --git a/src/filemanager/usermenu.c b/src/filemanager/usermenu.c
    index fc593b5..2d7d5f8 100644
    a b execute_menu_command (WEdit * edit_widget, const char *commands, gboolean show_p 
    550550    mc_chmod (file_name_vpath, S_IRWXU); 
    551551    if (run_view) 
    552552    { 
    553         mcview_viewer (vfs_path_as_str (file_name_vpath), NULL, 0); 
     553        mcview_viewer (vfs_path_as_str (file_name_vpath), NULL, 0, 0, 0); 
    554554        dialog_switch_process_pending (); 
    555555    } 
    556556    else 
  • src/viewer/actions_cmd.c

    diff --git a/src/viewer/actions_cmd.c b/src/viewer/actions_cmd.c
    index 20fdbf1..492dcfa 100644
    a b mcview_hook (void *v) 
    210210 
    211211    mcview_done (view); 
    212212    mcview_init (view); 
    213     mcview_load (view, 0, panel->dir.list[panel->selected].fname, 0); 
     213    mcview_load (view, 0, panel->dir.list[panel->selected].fname, 0, 0, 0); 
    214214    mcview_display (view); 
    215215} 
    216216 
    mcview_load_next_prev (mcview_t * view, int direction) 
    369369    mcview_remove_ext_script (view); 
    370370    mcview_init (view); 
    371371    if (regex_command_for (view, vfile, "View", &ext_script) == 0) 
    372         mcview_load (view, NULL, vfs_path_as_str (vfile), 0); 
     372        mcview_load (view, NULL, vfs_path_as_str (vfile), 0, 0, 0); 
    373373    vfs_path_free (vfile); 
    374374    view->dir = dir; 
    375375    view->dir_idx = dir_idx; 
  • src/viewer/lib.c

    diff --git a/src/viewer/lib.c b/src/viewer/lib.c
    index 2528c10..4d72f60 100644
    a b mcview_toggle_magic_mode (mcview_t * view) 
    9191    view->dir_idx = NULL; 
    9292    mcview_done (view); 
    9393    mcview_init (view); 
    94     mcview_load (view, command, filename, 0); 
     94    mcview_load (view, command, filename, 0, 0, 0); 
    9595    view->dir = dir; 
    9696    view->dir_idx = dir_idx; 
    9797    g_free (filename); 
  • src/viewer/mcviewer.c

    diff --git a/src/viewer/mcviewer.c b/src/viewer/mcviewer.c
    index a34099b..4dffd11 100644
    a b mcview_new (int y, int x, int lines, int cols, gboolean is_panel) 
    232232/** Real view only */ 
    233233 
    234234gboolean 
    235 mcview_viewer (const char *command, const vfs_path_t * file_vpath, int start_line) 
     235mcview_viewer (const char *command, const vfs_path_t * file_vpath, int start_line, off_t search_start, off_t search_end) 
    236236{ 
    237237    gboolean succeeded; 
    238238    mcview_t *lc_mcview; 
    mcview_viewer (const char *command, const vfs_path_t * file_vpath, int start_lin 
    249249 
    250250    view_dlg->get_title = mcview_get_title; 
    251251 
    252     succeeded = mcview_load (lc_mcview, command, vfs_path_as_str (file_vpath), start_line); 
     252    succeeded = mcview_load (lc_mcview, command, vfs_path_as_str (file_vpath), start_line, search_start, search_end); 
    253253 
    254254    if (succeeded) 
    255255        dlg_run (view_dlg); 
    mcview_viewer (const char *command, const vfs_path_t * file_vpath, int start_lin 
    267267/* --------------------------------------------------------------------------------------------- */ 
    268268 
    269269gboolean 
    270 mcview_load (mcview_t * view, const char *command, const char *file, int start_line) 
     270mcview_load (mcview_t * view, const char *command, const char *file, int start_line, off_t search_start, off_t search_end) 
    271271{ 
    272272    gboolean retval = FALSE; 
    273273    vfs_path_t *vpath = NULL; 
    mcview_load (mcview_t * view, const char *command, const char *file, int start_l 
    409409    mcview_state_machine_init (&view->dpy_state_top, 0); 
    410410    view->dpy_wrap_dirty = FALSE; 
    411411    view->force_max = -1; 
    412     view->search_start = 0; 
    413     view->search_end = 0; 
    414412    view->dpy_text_column = 0; 
    415413 
    416414    mcview_compute_areas (view); 
    mcview_load (mcview_t * view, const char *command, const char *file, int start_l 
    441439    else if (start_line > 0) 
    442440        mcview_moveto (view, start_line - 1, 0); 
    443441 
     442    view->search_start = search_start; 
     443    view->search_end = search_end; 
    444444    view->hexedit_lownibble = FALSE; 
    445445    view->hexview_in_text = FALSE; 
    446446    view->change_list = NULL; 
  • src/viewer/mcviewer.h

    diff --git a/src/viewer/mcviewer.h b/src/viewer/mcviewer.h
    index e68642b..89c4073 100644
    a b extern mcview_t *mcview_new (int y, int x, int lines, int cols, gboolean is_pane 
    4343/* Shows {file} or the output of {command} in the internal viewer, 
    4444 * starting in line {start_line}. 
    4545 */ 
    46 extern gboolean mcview_viewer (const char *command, const vfs_path_t * file_vpath, int start_line); 
     46extern gboolean mcview_viewer (const char *command, const vfs_path_t * file_vpath, int start_line, 
     47                               off_t search_start, off_t search_end); 
    4748 
    4849extern gboolean mcview_load (mcview_t * view, const char *command, const char *file, 
    49                              int start_line); 
     50                             int start_line, off_t search_start, off_t search_end); 
    5051 
    5152/*** inline functions ****************************************************************************/ 
    5253#endif /* MC__VIEWER_H */