Merge branch '2187_mc_e_mc_v'

* 2187_mc_e_mc_v:
  Fixed 'mc -e' and 'mc -v' modes.
  Ticket #2187: fix of broken 'mc -e' and 'mc -v' modes.
This commit is contained in:
Andrew Borodin 2010-05-14 11:28:32 +04:00
commit e14ddbd7a1
3 changed files with 229 additions and 153 deletions

View File

@ -31,11 +31,14 @@
#include "lib/global.h" #include "lib/global.h"
#include "lib/tty/tty.h" #include "lib/tty/tty.h"
#include "lib/tty/color.h" /* command_line_colors */ #include "lib/tty/color.h" /* command_line_colors */
#include "lib/tty/mouse.h"
#include "lib/strutil.h" #include "lib/strutil.h"
#include "lib/vfs/mc-vfs/vfs.h"
#include "lib/vfs/mc-vfs/smbfs.h" /* smbfs_set_debugf() */
#include "src/main.h" #include "src/main.h"
#include "src/textconf.h" #include "src/textconf.h"
#include "subshell.h" /* use_subshell */ #include "src/subshell.h" /* use_subshell */
#include "src/args.h" #include "src/args.h"
@ -44,7 +47,7 @@
/*** global variables ****************************************************************************/ /*** global variables ****************************************************************************/
/* If true, show version info and exit */ /* If true, show version info and exit */
gboolean mc_args__version = FALSE; gboolean mc_args__show_version = FALSE;
/* If true, assume we are running on an xterm terminal */ /* If true, assume we are running on an xterm terminal */
gboolean mc_args__force_xterm = FALSE; gboolean mc_args__force_xterm = FALSE;
@ -63,6 +66,9 @@ gboolean mc_args__disable_colors = FALSE;
/* Force colors, only used by Slang */ /* Force colors, only used by Slang */
gboolean mc_args__force_colors = FALSE; gboolean mc_args__force_colors = FALSE;
/* Line to start the editor on */
int mc_args__edit_start_line = 0;
/* Show in specified skin */ /* Show in specified skin */
char *mc_args__skin = NULL; char *mc_args__skin = NULL;
@ -77,13 +83,18 @@ char *mc_args__keymap_file = NULL;
/* Debug level */ /* Debug level */
int mc_args__debug_level = 0; int mc_args__debug_level = 0;
/*** file scope macro definitions ****************************************************************/ /*** file scope macro definitions ****************************************************************/
/*** file scope type declarations ****************************************************************/ /*** file scope type declarations ****************************************************************/
/*** file scope variables ************************************************************************/ /*** file scope variables ************************************************************************/
/* forward declarations */
static gboolean parse_mc_e_argument (const gchar *option_name, const gchar *value,
gpointer data, GError **error);
static gboolean parse_mc_v_argument (const gchar *option_name, const gchar *value,
gpointer data, GError **error);
static GOptionContext *context; static GOptionContext *context;
static gboolean mc_args__nouse_subshell = FALSE; static gboolean mc_args__nouse_subshell = FALSE;
@ -96,7 +107,7 @@ static const GOptionEntry argument_main_table[] = {
/* generic options */ /* generic options */
{ {
"version", 'V', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, "version", 'V', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
&mc_args__version, &mc_args__show_version,
N_("Displays the current version"), N_("Displays the current version"),
NULL NULL
}, },
@ -152,15 +163,15 @@ static const GOptionEntry argument_main_table[] = {
/* single file operations */ /* single file operations */
{ {
"view", 'v', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING, "view", 'v', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK,
&mc_run_param0, parse_mc_v_argument,
N_("Launches the file viewer on a file"), N_("Launches the file viewer on a file"),
"<file>" "<file>"
}, },
{ {
"edit", 'e', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING, "edit", 'e', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK,
&mc_run_param0, parse_mc_e_argument,
N_("Edits one file"), N_("Edits one file"),
"<file>"}, "<file>"},
@ -369,10 +380,172 @@ mc_args_add_extended_info_to_help (void)
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
static gboolean static void
mc_args_process (void) mc_setup_by_args (int argc, char *argv[])
{ {
if (mc_args__version) const char *base;
char *tmp;
if (mc_args__nomouse)
use_mouse_p = MOUSE_DISABLED;
#ifdef USE_NETCODE
if (mc_args__netfs_logfile != NULL)
{
mc_setctl ("/#ftp:", VFS_SETCTL_LOGFILE, (void *) mc_args__netfs_logfile);
#ifdef ENABLE_VFS_SMB
smbfs_set_debugf (mc_args__netfs_logfile);
#endif /* ENABLE_VFS_SMB */
}
#ifdef ENABLE_VFS_SMB
if (mc_args__debug_level != 0)
smbfs_set_debug (mc_args__debug_level);
#endif /* ENABLE_VFS_SMB */
#endif /* USE_NETCODE */
base = x_basename (argv[0]);
tmp = (argc > 0) ? argv[1] : NULL;
if (strncmp (base, "mce", 3) == 0 || strcmp (base, "vi") == 0)
{
/* mce* or vi is link to mc */
mc_run_param0 = g_strdup ("");
if (tmp != NULL)
{
/*
* Check for filename:lineno, followed by an optional colon.
* This format is used by many programs (especially compilers)
* in error messages and warnings. It is supported so that
* users can quickly copy and paste file locations.
*/
char *end, *p;
end = tmp + strlen (tmp);\
p = end;
if (p > tmp && p[-1] == ':')
p--;
while (p > tmp && g_ascii_isdigit ((gchar) p[-1]))
p--;
if (tmp < p && p < end && p[-1] == ':')
{
char *fname;
struct stat st;
fname = g_strndup (tmp, p - 1 - tmp);
/*
* Check that the file before the colon actually exists.
* If it doesn't exist, revert to the old behavior.
*/
if (mc_stat (tmp, &st) == -1 && mc_stat (fname, &st) != -1)
{
mc_run_param0 = fname;
mc_args__edit_start_line = atoi (p);
}
else
{
g_free (fname);
goto try_plus_filename;
}
}
else
{
try_plus_filename:
if (*tmp == '+' && g_ascii_isdigit ((gchar) tmp[1]))
{
int start_line;;
start_line = atoi (tmp);
if (start_line > 0)
{
char *file;
file = (argc > 1) ? argv[2] : NULL;
if (file != NULL)
{
tmp = file;
mc_args__edit_start_line = start_line;
}
}
}
mc_run_param0 = g_strdup (tmp);
}
}
mc_run_mode = MC_RUN_EDITOR;
}
else if (strncmp (base, "mcv", 3) == 0 || strcmp (base, "view") == 0)
{
/* mcv* or view is link to mc */
if (tmp != NULL)
mc_run_param0 = g_strdup (tmp);
else
{
fprintf (stderr, "%s\n", _("No arguments given to the viewer."));
exit (EXIT_FAILURE);
}
mc_run_mode = MC_RUN_VIEWER;
}
#ifdef USE_DIFF_VIEW
else if (strncmp (base, "mcd", 3) == 0 || strcmp (base, "diff") == 0)
{
/* mcd* or diff is link to mc */
if (argc < 3)
{
fprintf (stderr, "%s\n", _("There 2 files are required to diffviewer."));
exit (EXIT_FAILURE);
}
if (tmp != NULL)
{
mc_run_param0 = g_strdup (tmp);
tmp = (argc > 1) ? argv[2] : NULL;
if (tmp != NULL)
mc_run_param1 = g_strdup (tmp);
mc_run_mode = MC_RUN_DIFFVIEWER;
}
}
#endif /* USE_DIFF_VIEW */
else
{
/* MC is run as mc */
switch (mc_run_mode)
{
case MC_RUN_EDITOR:
case MC_RUN_VIEWER:
/* mc_run_param0 is set up in parse_mc_e_argument() and parse_mc_v_argument() */
break;
case MC_RUN_DIFFVIEWER:
/* not implemented yet */
break;
case MC_RUN_FULL:
default:
/* sets the current dir and the other dir */
if (tmp != NULL)
{
mc_run_param0 = g_strdup (tmp);
tmp = (argc > 1) ? argv[2] : NULL;
if (tmp != NULL)
mc_run_param1 = g_strdup (tmp);
}
mc_run_mode = MC_RUN_FULL;
break;
}
}
}
/* --------------------------------------------------------------------------------------------- */
static gboolean
mc_args_process (int argc, char *argv[])
{
if (mc_args__show_version)
{ {
show_version (); show_version ();
return FALSE; return FALSE;
@ -394,6 +567,8 @@ mc_args_process (void)
use_subshell = 0; use_subshell = 0;
#endif /* HAVE_SUBSHELL_SUPPORT */ #endif /* HAVE_SUBSHELL_SUPPORT */
mc_setup_by_args (argc, argv);
return TRUE; return TRUE;
} }
@ -417,12 +592,44 @@ mc_args__convert_help_to_syscharset (const gchar * charset, const gchar * error_
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
static gboolean
parse_mc_e_argument (const gchar *option_name, const gchar *value,
gpointer data, GError **error)
{
(void) option_name;
(void) data;
(void) error;
mc_run_mode = MC_RUN_EDITOR;
mc_run_param0 = g_strdup (value);
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
static gboolean
parse_mc_v_argument (const gchar *option_name, const gchar *value,
gpointer data, GError **error)
{
(void) option_name;
(void) data;
(void) error;
mc_run_mode = MC_RUN_VIEWER;
mc_run_param0 = g_strdup (value);
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/*** public functions ****************************************************************************/ /*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
gboolean gboolean
mc_args_handle (int *argc, char ***argv, const gchar * translation_domain) mc_args_handle (int argc, char **argv, const char *translation_domain)
{ {
GError *error = NULL; GError *error = NULL;
const gchar *_system_codepage = str_detect_termencoding (); const gchar *_system_codepage = str_detect_termencoding ();
@ -444,7 +651,6 @@ mc_args_handle (int *argc, char ***argv, const gchar * translation_domain)
g_option_context_set_main_group (context, main_group); g_option_context_set_main_group (context, main_group);
g_option_group_set_translation_domain (main_group, translation_domain); g_option_group_set_translation_domain (main_group, translation_domain);
terminal_group = g_option_group_new ("terminal", _("Terminal options"), terminal_group = g_option_group_new ("terminal", _("Terminal options"),
_("Terminal options"), NULL, NULL); _("Terminal options"), NULL, NULL);
@ -452,14 +658,13 @@ mc_args_handle (int *argc, char ***argv, const gchar * translation_domain)
g_option_context_add_group (context, terminal_group); g_option_context_add_group (context, terminal_group);
g_option_group_set_translation_domain (terminal_group, translation_domain); g_option_group_set_translation_domain (terminal_group, translation_domain);
color_group = mc_args_new_color_group (); color_group = mc_args_new_color_group ();
g_option_group_add_entries (color_group, argument_color_table); g_option_group_add_entries (color_group, argument_color_table);
g_option_context_add_group (context, color_group); g_option_context_add_group (context, color_group);
g_option_group_set_translation_domain (color_group, translation_domain); g_option_group_set_translation_domain (color_group, translation_domain);
if (!g_option_context_parse (context, argc, argv, &error)) if (!g_option_context_parse (context, &argc, &argv, &error))
{ {
if (error != NULL) if (error != NULL)
{ {
@ -497,7 +702,7 @@ mc_args_handle (int *argc, char ***argv, const gchar * translation_domain)
bind_textdomain_codeset ("mc", _system_codepage); bind_textdomain_codeset ("mc", _system_codepage);
#endif #endif
return mc_args_process (); return mc_args_process (argc, argv);
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */

View File

@ -1,6 +1,8 @@
#ifndef MC__ARGS_H #ifndef MC__ARGS_H
#define MC__ARGS_H #define MC__ARGS_H
#include "lib/global.h" /* gboolean */
/*** typedefs(not structures) and defined constants **********************************************/ /*** typedefs(not structures) and defined constants **********************************************/
/*** enums ***************************************************************************************/ /*** enums ***************************************************************************************/
@ -17,6 +19,7 @@ extern gboolean mc_args__disable_colors;
extern gboolean mc_args__force_colors; extern gboolean mc_args__force_colors;
extern char *mc_args__skin; extern char *mc_args__skin;
extern gboolean mc_args__version; extern gboolean mc_args__version;
extern int mc_args__edit_start_line;
extern char *mc_args__last_wd_file; extern char *mc_args__last_wd_file;
extern char *mc_args__netfs_logfile; extern char *mc_args__netfs_logfile;
extern char *mc_args__keymap_file; extern char *mc_args__keymap_file;
@ -24,6 +27,6 @@ extern int mc_args__debug_level;
/*** declarations of public functions ************************************************************/ /*** declarations of public functions ************************************************************/
gboolean mc_args_handle(int *, char ***, const gchar *); gboolean mc_args_handle(int argc, char **argv, const char *translation_domain);
#endif #endif /* MC__ARGS_H */

View File

@ -277,9 +277,6 @@ mc_run_mode_t mc_run_mode = MC_RUN_FULL;
char *mc_run_param0 = NULL; char *mc_run_param0 = NULL;
char *mc_run_param1 = NULL; char *mc_run_param1 = NULL;
/* Line to start the editor on */
static int edit_one_file_start_line = 0;
/* Used so that widgets know if they are being destroyed or /* Used so that widgets know if they are being destroyed or
shut down */ shut down */
int midnight_shutdown = 0; int midnight_shutdown = 0;
@ -1904,7 +1901,7 @@ mc_maybe_editor_or_viewer (void)
{ {
#ifdef USE_INTERNAL_EDIT #ifdef USE_INTERNAL_EDIT
case MC_RUN_EDITOR: case MC_RUN_EDITOR:
edit_file (mc_run_param0, edit_one_file_start_line); edit_file (mc_run_param0, mc_args__edit_start_line);
break; break;
#endif /* USE_INTERNAL_EDIT */ #endif /* USE_INTERNAL_EDIT */
case MC_RUN_VIEWER: case MC_RUN_VIEWER:
@ -2087,133 +2084,6 @@ init_sigchld (void)
} }
} }
static void
mc_main__setup_by_args (int argc, char *argv[])
{
const char *base;
char *tmp;
if (mc_args__nomouse)
use_mouse_p = MOUSE_DISABLED;
#ifdef USE_NETCODE
if (mc_args__netfs_logfile != NULL)
{
mc_setctl ("/#ftp:", VFS_SETCTL_LOGFILE, (void *) mc_args__netfs_logfile);
#ifdef ENABLE_VFS_SMB
smbfs_set_debugf (mc_args__netfs_logfile);
#endif /* ENABLE_VFS_SMB */
}
#ifdef ENABLE_VFS_SMB
if (mc_args__debug_level != 0)
smbfs_set_debug (mc_args__debug_level);
#endif /* ENABLE_VFS_SMB */
#endif /* USE_NETCODE */
base = x_basename (argv[0]);
tmp = (argc > 0) ? argv[1] : NULL;
if (!STRNCOMP (base, "mce", 3) || !STRCOMP (base, "vi"))
{
mc_run_param0 = g_strdup ("");
if (tmp != NULL)
{
/*
* Check for filename:lineno, followed by an optional colon.
* This format is used by many programs (especially compilers)
* in error messages and warnings. It is supported so that
* users can quickly copy and paste file locations.
*/
char *end = tmp + strlen (tmp), *p = end;
if (p > tmp && p[-1] == ':')
p--;
while (p > tmp && g_ascii_isdigit ((gchar) p[-1]))
p--;
if (tmp < p && p < end && p[-1] == ':')
{
struct stat st;
gchar *fname = g_strndup (tmp, p - 1 - tmp);
/*
* Check that the file before the colon actually exists.
* If it doesn't exist, revert to the old behavior.
*/
if (mc_stat (tmp, &st) == -1 && mc_stat (fname, &st) != -1)
{
mc_run_param0 = fname;
edit_one_file_start_line = atoi (p);
}
else
{
g_free (fname);
goto try_plus_filename;
}
}
else
{
try_plus_filename:
if (*tmp == '+' && g_ascii_isdigit ((gchar) tmp[1]))
{
int start_line = atoi (tmp);
if (start_line > 0)
{
char *file = (argc > 1) ? argv[2] : NULL;
if (file)
{
tmp = file;
edit_one_file_start_line = start_line;
}
}
}
mc_run_param0 = g_strdup (tmp);
}
}
mc_run_mode = MC_RUN_EDITOR;
}
else if (!STRNCOMP (base, "mcv", 3) || !STRCOMP (base, "view"))
{
if (tmp != NULL)
mc_run_param0 = g_strdup (tmp);
else
{
fputs ("No arguments given to the viewer\n", stderr);
exit (EXIT_FAILURE);
}
mc_run_mode = MC_RUN_VIEWER;
}
#ifdef USE_DIFF_VIEW
else if (!STRNCOMP (base, "mcd", 3) || !STRCOMP (base, "diff"))
{
if (argc < 3)
{
fputs ("There 2 files are required to diffviewer\n", stderr);
exit (EXIT_FAILURE);
}
if (tmp != NULL)
{
mc_run_param0 = g_strdup (tmp);
tmp = (argc > 1) ? argv[2] : NULL;
if (tmp != NULL)
mc_run_param1 = g_strdup (tmp);
mc_run_mode = MC_RUN_DIFFVIEWER;
}
}
#endif /* USE_DIFF_VIEW */
else
{
/* sets the current dir and the other dir */
if (tmp != NULL)
{
mc_run_param0 = g_strdup (tmp);
tmp = (argc > 1) ? argv[2] : NULL;
if (tmp != NULL)
mc_run_param1 = g_strdup (tmp);
}
mc_run_mode = MC_RUN_FULL;
}
}
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
@ -2244,10 +2114,8 @@ main (int argc, char *argv[])
SLtt_Ignore_Beep = 1; SLtt_Ignore_Beep = 1;
#endif #endif
if (!mc_args_handle (&argc, &argv, "mc")) if (!mc_args_handle (argc, argv, "mc"))
return 1; exit (EXIT_FAILURE);
mc_main__setup_by_args (argc, argv);
/* NOTE: This has to be called before tty_init or whatever routine /* NOTE: This has to be called before tty_init or whatever routine
calls any define_sequence */ calls any define_sequence */