1
1

Merge branch '2769_compare_files_crash'

* 2769_compare_files_crash:
  (diff_view): make static.
  Make mcdiff verbose if one or both parameters are incorrect.
  Ticket #2769: crash on compare files if one panel is not in the listing mode.
Этот коммит содержится в:
Andrew Borodin 2012-04-04 13:57:41 +04:00
родитель c494f7b3bb b4efe67b12
Коммит d25ac6a911
4 изменённых файлов: 97 добавлений и 25 удалений

Просмотреть файл

@ -42,11 +42,12 @@
#include "lib/vfs/vfs.h" /* mc_opendir, mc_readdir, mc_closedir, */
#include "lib/util.h"
#include "lib/widget.h"
#include "lib/strutil.h"
#include "lib/charsets.h"
#include "lib/event.h" /* mc_event_raise() */
#include "src/filemanager/cmd.h"
#include "src/filemanager/midnight.h" /* Needed for current_panel and other_panel */
#include "src/filemanager/cmd.h" /* do_edit_at_line(), view_other_cmd() */
#include "src/filemanager/panel.h"
#include "src/filemanager/layout.h" /* Needed for get_current_index and get_other_panel */
#include "src/keybind-defaults.h"
@ -3296,10 +3297,9 @@ dview_get_title (const Dlg_head * h, size_t len)
return g_string_free (title, FALSE);
}
/*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */
int
static int
diff_view (const char *file1, const char *file2, const char *label1, const char *label2)
{
int error;
@ -3338,6 +3338,7 @@ diff_view (const char *file1, const char *file2, const char *label1, const char
return error == 0 ? 1 : 0;
}
/*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */
#define GET_FILE_AND_STAMP(n) \
@ -3377,34 +3378,96 @@ do \
} \
while (0)
void
dview_diff_cmd (void)
int
dview_diff_cmd (const void *f0, const void *f1)
{
int rv = 0;
vfs_path_t *file0 = NULL;
vfs_path_t *file1 = NULL;
int is_dir0 = 0;
int is_dir1 = 0;
gboolean is_dir0 = FALSE;
gboolean is_dir1 = FALSE;
if (mc_global.mc_run_mode == MC_RUN_FULL)
switch (mc_global.mc_run_mode)
{
const WPanel *panel0 = current_panel;
const WPanel *panel1 = other_panel;
if (get_current_index ())
case MC_RUN_FULL:
{
panel0 = other_panel;
panel1 = current_panel;
/* run from panels */
const WPanel *panel0 = (const WPanel *) f0;
const WPanel *panel1 = (const WPanel *) f1;
file0 = vfs_path_append_new (panel0->cwd_vpath, selection (panel0)->fname, NULL);
is_dir0 = S_ISDIR (selection (panel0)->st.st_mode);
if (is_dir0)
{
message (D_ERROR, MSG_ERROR, _("\"%s\" is a directory"),
path_trunc (selection (panel0)->fname, 30));
goto ret;
}
file1 = vfs_path_append_new (panel1->cwd_vpath, selection (panel1)->fname, NULL);
is_dir1 = S_ISDIR (selection (panel1)->st.st_mode);
if (is_dir1)
{
message (D_ERROR, MSG_ERROR, _("\"%s\" is a directory"),
path_trunc (selection (panel1)->fname, 30));
goto ret;
}
break;
}
file0 = vfs_path_append_new (panel0->cwd_vpath, selection (panel0)->fname, NULL);
file1 = vfs_path_append_new (panel1->cwd_vpath, selection (panel1)->fname, NULL);
is_dir0 = S_ISDIR (selection (panel0)->st.st_mode);
is_dir1 = S_ISDIR (selection (panel1)->st.st_mode);
case MC_RUN_DIFFVIEWER:
{
/* run from command line */
const char *p0 = (const char *) f0;
const char *p1 = (const char *) f1;
struct stat st;
file0 = vfs_path_from_str (p0);
if (mc_stat (file0, &st) == 0)
{
is_dir0 = S_ISDIR (st.st_mode);
if (is_dir0)
{
message (D_ERROR, MSG_ERROR, _("\"%s\" is a directory"), path_trunc (p0, 30));
goto ret;
}
}
else
{
message (D_ERROR, MSG_ERROR, _("Cannot stat \"%s\"\n%s"),
path_trunc (p0, 30), unix_error_string (errno));
goto ret;
}
file1 = vfs_path_from_str (p1);
if (mc_stat (file1, &st) == 0)
{
is_dir1 = S_ISDIR (st.st_mode);
if (is_dir1)
{
message (D_ERROR, MSG_ERROR, _("\"%s\" is a directory"), path_trunc (p1, 30));
goto ret;
}
}
else
{
message (D_ERROR, MSG_ERROR, _("Cannot stat \"%s\"\n%s"),
path_trunc (p1, 30), unix_error_string (errno));
goto ret;
}
break;
}
default:
/* this should not happaned */
message (D_ERROR, MSG_ERROR, _("Diff viewer: invalid mode"));
return 0;
}
if (rv == 0)
{
rv = -1;
if (file0 != NULL && !is_dir0 && file1 != NULL && !is_dir1)
if (file0 != NULL && file1 != NULL)
{
int use_copy0;
int use_copy1;
@ -3435,11 +3498,14 @@ dview_diff_cmd (void)
}
}
if (rv == 0)
message (D_ERROR, MSG_ERROR, _("Two files are needed to compare"));
ret:
vfs_path_free (file1);
vfs_path_free (file0);
if (rv == 0)
message (D_ERROR, MSG_ERROR, _("Two files are needed to compare"));
return (rv != 0) ? 1 : 0;
}
/* --------------------------------------------------------------------------------------------- */

Просмотреть файл

@ -11,7 +11,6 @@
/*** declarations of public functions ************************************************************/
void dview_diff_cmd (void);
int diff_view (const char *file1, const char *file2, const char *label1, const char *label2);
int dview_diff_cmd (const void *f0, const void *f1);
#endif /* MC__DIFFVIEW_YDIFF_H */

Просмотреть файл

@ -1329,7 +1329,14 @@ compare_dirs_cmd (void)
void
diff_view_cmd (void)
{
dview_diff_cmd ();
/* both panels must be in the list mode */
if (get_current_type () != view_listing || get_other_type () != view_listing)
return;
if (get_current_index () == 0)
dview_diff_cmd (current_panel, other_panel);
else
dview_diff_cmd (other_panel, current_panel);
if (mc_global.mc_run_mode == MC_RUN_FULL)
update_panels (UP_OPTIMIZE, UP_KEEPSEL);

Просмотреть файл

@ -978,7 +978,7 @@ mc_maybe_editor_or_viewer (void)
}
#ifdef USE_DIFF_VIEW
case MC_RUN_DIFFVIEWER:
ret = diff_view (mc_run_param0, mc_run_param1, mc_run_param0, mc_run_param1);
ret = dview_diff_cmd (mc_run_param0, mc_run_param1);
break;
#endif /* USE_DIFF_VIEW */
default: