mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 04:22:34 +03:00
Add src/execute.c:execute_external_editor_or_viewer() function.
Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
parent
2406284762
commit
2a2bc56221
105
src/execute.c
105
src/execute.c
@ -63,6 +63,9 @@ int pause_after_run = pause_on_dumb_terminals;
|
||||
/*** file scope functions ************************************************************************/
|
||||
|
||||
void do_execute (const char *shell, const char *command, int flags);
|
||||
void do_executev (const char *shell, int flags, char *const argv[]);
|
||||
char *execute_get_external_cmd_opts_from_config (const char *command,
|
||||
const vfs_path_t * filename_vpath, int start_line);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
@ -164,7 +167,8 @@ do_suspend_cmd (void)
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static gboolean
|
||||
execute_prepare_with_vfs_arg (const vfs_path_t * filename_vpath, vfs_path_t ** localcopy_vpath, time_t *mtime)
|
||||
execute_prepare_with_vfs_arg (const vfs_path_t * filename_vpath, vfs_path_t ** localcopy_vpath,
|
||||
time_t * mtime)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
@ -196,7 +200,8 @@ execute_prepare_with_vfs_arg (const vfs_path_t * filename_vpath, vfs_path_t ** l
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
execute_cleanup_with_vfs_arg (const vfs_path_t * filename_vpath, vfs_path_t ** localcopy_vpath, time_t *mtime)
|
||||
execute_cleanup_with_vfs_arg (const vfs_path_t * filename_vpath, vfs_path_t ** localcopy_vpath,
|
||||
time_t * mtime)
|
||||
{
|
||||
if (*localcopy_vpath != NULL)
|
||||
{
|
||||
@ -218,8 +223,23 @@ execute_cleanup_with_vfs_arg (const vfs_path_t * filename_vpath, vfs_path_t ** l
|
||||
/*** public functions ****************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
char *
|
||||
execute_get_external_cmd_opts_from_config (const char *command, const vfs_path_t * filename_vpath,
|
||||
int start_line)
|
||||
{
|
||||
(void) command;
|
||||
(void) start_line;
|
||||
|
||||
if (filename_vpath == NULL)
|
||||
return g_strdup ("");
|
||||
|
||||
return g_strdup (vfs_path_get_last_path_str (filename_vpath));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
do_execute (const char *shell, const char *command, int flags)
|
||||
do_executev (const char *shell, int flags, char *const argv[])
|
||||
{
|
||||
#ifdef ENABLE_SUBSHELL
|
||||
vfs_path_t *new_dir_vpath = NULL;
|
||||
@ -236,24 +256,24 @@ do_execute (const char *shell, const char *command, int flags)
|
||||
if (mc_global.tty.console_flag != '\0')
|
||||
handle_console (CONSOLE_RESTORE);
|
||||
|
||||
if (!mc_global.tty.use_subshell && command && !(flags & EXECUTE_INTERNAL))
|
||||
if (!mc_global.tty.use_subshell && *argv != NULL && (flags & EXECUTE_INTERNAL) == 0)
|
||||
{
|
||||
printf ("%s%s\n", mc_prompt, command);
|
||||
printf ("%s%s\n", mc_prompt, *argv);
|
||||
fflush (stdout);
|
||||
}
|
||||
#ifdef ENABLE_SUBSHELL
|
||||
if (mc_global.tty.use_subshell && !(flags & EXECUTE_INTERNAL))
|
||||
if (mc_global.tty.use_subshell && (flags & EXECUTE_INTERNAL) == 0)
|
||||
{
|
||||
do_update_prompt ();
|
||||
|
||||
/* We don't care if it died, higher level takes care of this */
|
||||
invoke_subshell (command, VISIBLY, old_vfs_dir_vpath != NULL ? NULL : &new_dir_vpath);
|
||||
invoke_subshell (*argv, VISIBLY, old_vfs_dir_vpath != NULL ? NULL : &new_dir_vpath);
|
||||
}
|
||||
else
|
||||
#endif /* ENABLE_SUBSHELL */
|
||||
my_system (flags, shell, command);
|
||||
my_systemv_flags (flags, shell, argv);
|
||||
|
||||
if (!(flags & EXECUTE_INTERNAL))
|
||||
if ((flags & EXECUTE_INTERNAL) == 0)
|
||||
{
|
||||
if ((pause_after_run == pause_always
|
||||
|| (pause_after_run == pause_on_dumb_terminals && !mc_global.tty.xterm_flag
|
||||
@ -270,13 +290,10 @@ do_execute (const char *shell, const char *command, int flags)
|
||||
printf ("\r\n");
|
||||
fflush (stdout);
|
||||
}
|
||||
if (mc_global.tty.console_flag != '\0')
|
||||
if (mc_global.tty.console_flag != '\0' && output_lines != 0 && mc_global.keybar_visible)
|
||||
{
|
||||
if (output_lines && mc_global.keybar_visible)
|
||||
{
|
||||
putchar ('\n');
|
||||
fflush (stdout);
|
||||
}
|
||||
putchar ('\n');
|
||||
fflush (stdout);
|
||||
}
|
||||
}
|
||||
|
||||
@ -311,6 +328,22 @@ do_execute (const char *shell, const char *command, int flags)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
do_execute (const char *shell, const char *command, int flags)
|
||||
{
|
||||
GPtrArray *args_array;
|
||||
|
||||
args_array = g_ptr_array_new ();
|
||||
g_ptr_array_add (args_array, (char *) command);
|
||||
g_ptr_array_add (args_array, NULL);
|
||||
|
||||
do_executev (shell, flags, (char *const *) args_array->pdata);
|
||||
|
||||
g_ptr_array_free (args_array, TRUE);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/** Set up the terminal before executing a program */
|
||||
|
||||
void
|
||||
@ -527,3 +560,45 @@ execute_with_vfs_arg (const char *command, const vfs_path_t * filename_vpath)
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Execute external editor or viewer.
|
||||
*
|
||||
* @param command editor/viewer to run
|
||||
* @param filename_vpath path for edit/view
|
||||
* @param start_line cursor will be placed at the 'start_line' position after opening file
|
||||
*/
|
||||
|
||||
void
|
||||
execute_external_editor_or_viewer (const char *command, const vfs_path_t * filename_vpath,
|
||||
int start_line)
|
||||
{
|
||||
vfs_path_t *localcopy_vpath = NULL;
|
||||
const vfs_path_t *do_execute_vpath;
|
||||
char *extern_cmd_options;
|
||||
time_t mtime;
|
||||
|
||||
if (!execute_prepare_with_vfs_arg (filename_vpath, &localcopy_vpath, &mtime))
|
||||
return;
|
||||
|
||||
do_execute_vpath = (localcopy_vpath == NULL) ? filename_vpath : localcopy_vpath;
|
||||
|
||||
extern_cmd_options =
|
||||
execute_get_external_cmd_opts_from_config (command, do_execute_vpath, start_line);
|
||||
|
||||
if (extern_cmd_options != NULL)
|
||||
{
|
||||
char **argv_cmd_options;
|
||||
int argv_count;
|
||||
|
||||
g_shell_parse_argv (extern_cmd_options, &argv_count, &argv_cmd_options, NULL);
|
||||
g_free (extern_cmd_options);
|
||||
|
||||
do_executev (command, EXECUTE_INTERNAL, argv_cmd_options);
|
||||
|
||||
g_strfreev (argv_cmd_options);
|
||||
}
|
||||
|
||||
execute_cleanup_with_vfs_arg (filename_vpath, &localcopy_vpath, &mtime);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -43,6 +43,8 @@ gboolean execute_suspend (const gchar * event_group_name, const gchar * event_na
|
||||
|
||||
/* Execute command on a filename that can be on VFS */
|
||||
void execute_with_vfs_arg (const char *command, const vfs_path_t * filename_vpath);
|
||||
void execute_external_editor_or_viewer (const char *command, const vfs_path_t * filename_vpath,
|
||||
int start_line);
|
||||
|
||||
void post_exec (void);
|
||||
void pre_exec (void);
|
||||
|
@ -669,7 +669,7 @@ view_file_at_line (const vfs_path_t * filename_vpath, int plain_view, int intern
|
||||
viewer = "view";
|
||||
}
|
||||
|
||||
execute_with_vfs_arg (viewer, filename_vpath);
|
||||
execute_external_editor_or_viewer (viewer, filename_vpath, start_line);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -769,8 +769,6 @@ do_edit_at_line (const vfs_path_t * what_vpath, gboolean internal, int start_lin
|
||||
if (internal)
|
||||
edit_file (what_vpath, start_line);
|
||||
else
|
||||
#else
|
||||
(void) start_line;
|
||||
#endif /* USE_INTERNAL_EDIT */
|
||||
{
|
||||
if (editor == NULL)
|
||||
@ -779,7 +777,7 @@ do_edit_at_line (const vfs_path_t * what_vpath, gboolean internal, int start_lin
|
||||
if (editor == NULL)
|
||||
editor = get_default_editor ();
|
||||
}
|
||||
execute_with_vfs_arg (editor, what_vpath);
|
||||
execute_external_editor_or_viewer (editor, what_vpath, start_line);
|
||||
}
|
||||
|
||||
if (mc_global.mc_run_mode == MC_RUN_FULL)
|
||||
|
@ -20,9 +20,14 @@ endif
|
||||
EXTRA_DIST = execute__common.c
|
||||
|
||||
TESTS = \
|
||||
execute__execute_with_vfs_arg
|
||||
execute__execute_with_vfs_arg \
|
||||
execute__execute_external_editor_or_viewer
|
||||
|
||||
check_PROGRAMS = $(TESTS)
|
||||
|
||||
execute__execute_with_vfs_arg_SOURCES = \
|
||||
execute__execute_with_vfs_arg.c
|
||||
|
||||
|
||||
execute__execute_external_editor_or_viewer_SOURCES = \
|
||||
execute__execute_external_editor_or_viewer.c
|
@ -110,14 +110,14 @@ mc_getlocalcopy (const vfs_path_t * pathname_vpath)
|
||||
}
|
||||
|
||||
static void
|
||||
mc_getlocalcopy__init ()
|
||||
mc_getlocalcopy__init (void)
|
||||
{
|
||||
mc_getlocalcopy__pathname_vpath__captured = NULL;
|
||||
mc_getlocalcopy__return_value = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
mc_getlocalcopy__deinit ()
|
||||
mc_getlocalcopy__deinit (void)
|
||||
{
|
||||
vfs_path_free (mc_getlocalcopy__pathname_vpath__captured);
|
||||
}
|
||||
@ -151,7 +151,7 @@ message (int flags, const char *title, const char *text, ...)
|
||||
}
|
||||
|
||||
static void
|
||||
message__init ()
|
||||
message__init (void)
|
||||
{
|
||||
message_flags__captured = 0;
|
||||
message_title__captured = NULL;
|
||||
@ -159,7 +159,7 @@ message__init ()
|
||||
}
|
||||
|
||||
static void
|
||||
message__deinit ()
|
||||
message__deinit (void)
|
||||
{
|
||||
g_free (message_title__captured);
|
||||
g_free (message_text__captured);
|
||||
@ -184,13 +184,13 @@ mc_stat (const vfs_path_t * vpath, struct stat *stat_ignored)
|
||||
|
||||
|
||||
static void
|
||||
mc_stat__init ()
|
||||
mc_stat__init (void)
|
||||
{
|
||||
mc_stat__vpath__captured = g_ptr_array_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
mc_stat__deinit ()
|
||||
mc_stat__deinit (void)
|
||||
{
|
||||
g_ptr_array_foreach (mc_stat__vpath__captured, (GFunc) vfs_path_free, NULL);
|
||||
g_ptr_array_free (mc_stat__vpath__captured, TRUE);
|
||||
@ -218,14 +218,14 @@ mc_ungetlocalcopy (const vfs_path_t * pathname_vpath, const vfs_path_t * local_v
|
||||
}
|
||||
|
||||
static void
|
||||
mc_ungetlocalcopy__init ()
|
||||
mc_ungetlocalcopy__init (void)
|
||||
{
|
||||
mc_ungetlocalcopy__pathname_vpath__captured = NULL;
|
||||
mc_ungetlocalcopy__local_vpath__captured = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
mc_ungetlocalcopy__deinit ()
|
||||
mc_ungetlocalcopy__deinit (void)
|
||||
{
|
||||
vfs_path_free (mc_ungetlocalcopy__pathname_vpath__captured);
|
||||
vfs_path_free (mc_ungetlocalcopy__local_vpath__captured);
|
||||
|
211
tests/src/execute__execute_external_editor_or_viewer.c
Normal file
211
tests/src/execute__execute_external_editor_or_viewer.c
Normal file
@ -0,0 +1,211 @@
|
||||
/*
|
||||
src - tests for execute_external_editor_or_viewer() function
|
||||
|
||||
Copyright (C) 2013
|
||||
The Free Software Foundation, Inc.
|
||||
|
||||
Written by:
|
||||
Slava Zanko <slavazanko@gmail.com>, 2013
|
||||
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define TEST_SUITE_NAME "/src"
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <check.h>
|
||||
|
||||
#include "lib/global.h"
|
||||
|
||||
#include "execute__common.c"
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
char *execute_get_external_cmd_opts_from_config (const char *command,
|
||||
const vfs_path_t * filename_vpath, int start_line);
|
||||
|
||||
/* @CapturedValue */
|
||||
static char *execute_external_cmd_opts__command__captured;
|
||||
/* @CapturedValue */
|
||||
static vfs_path_t *execute_external_cmd_opts__filename_vpath__captured;
|
||||
/* @CapturedValue */
|
||||
static int execute_external_cmd_opts__start_line__captured;
|
||||
|
||||
/* @ThenReturnValue */
|
||||
static char *execute_external_cmd_opts__return_value;
|
||||
|
||||
/* @Mock */
|
||||
char *
|
||||
execute_get_external_cmd_opts_from_config (const char *command, const vfs_path_t * filename_vpath,
|
||||
int start_line)
|
||||
{
|
||||
execute_external_cmd_opts__command__captured = g_strdup (command);
|
||||
execute_external_cmd_opts__filename_vpath__captured = vfs_path_clone (filename_vpath);
|
||||
execute_external_cmd_opts__start_line__captured = start_line;
|
||||
|
||||
return execute_external_cmd_opts__return_value;
|
||||
}
|
||||
|
||||
static void
|
||||
execute_get_external_cmd_opts_from_config__init (void)
|
||||
{
|
||||
execute_external_cmd_opts__command__captured = NULL;
|
||||
execute_external_cmd_opts__filename_vpath__captured = NULL;
|
||||
execute_external_cmd_opts__start_line__captured = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
execute_get_external_cmd_opts_from_config__deinit (void)
|
||||
{
|
||||
g_free (execute_external_cmd_opts__command__captured);
|
||||
vfs_path_free (execute_external_cmd_opts__filename_vpath__captured);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
void do_executev (const char *lc_shell, int flags, char *const argv[]);
|
||||
|
||||
/* @CapturedValue */
|
||||
static char *do_executev__lc_shell__captured;
|
||||
/* @CapturedValue */
|
||||
static int do_executev__flags__captured;
|
||||
/* @CapturedValue */
|
||||
static GPtrArray *do_executev__argv__captured;
|
||||
|
||||
/* @Mock */
|
||||
void
|
||||
do_executev (const char *lc_shell, int flags, char *const argv[])
|
||||
{
|
||||
do_executev__lc_shell__captured = g_strdup (lc_shell);
|
||||
do_executev__flags__captured = flags;
|
||||
|
||||
for (; argv != NULL && *argv != NULL; argv++)
|
||||
g_ptr_array_add (do_executev__argv__captured, g_strdup (*argv));
|
||||
}
|
||||
|
||||
static void
|
||||
do_executev__init (void)
|
||||
{
|
||||
do_executev__lc_shell__captured = NULL;
|
||||
do_executev__argv__captured = g_ptr_array_new ();
|
||||
do_executev__flags__captured = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
do_executev__deinit (void)
|
||||
{
|
||||
g_free (do_executev__lc_shell__captured);
|
||||
g_ptr_array_foreach (do_executev__argv__captured, (GFunc) g_free, NULL);
|
||||
g_ptr_array_free (do_executev__argv__captured, TRUE);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* @Before */
|
||||
static void
|
||||
my_setup (void)
|
||||
{
|
||||
setup ();
|
||||
|
||||
execute_get_external_cmd_opts_from_config__init ();
|
||||
do_executev__init ();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* @After */
|
||||
static void
|
||||
my_teardown (void)
|
||||
{
|
||||
do_executev__deinit ();
|
||||
execute_get_external_cmd_opts_from_config__deinit ();
|
||||
|
||||
teardown ();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* @Test */
|
||||
/* *INDENT-OFF* */
|
||||
START_TEST (do_open_external_editor_or_viewer)
|
||||
/* *INDENT-ON* */
|
||||
{
|
||||
/* given */
|
||||
vfs_path_t *filename_vpath;
|
||||
filename_vpath = vfs_path_from_str ("/path/to/file.txt");
|
||||
|
||||
vfs_file_is_local__return_value = TRUE;
|
||||
execute_external_cmd_opts__return_value =
|
||||
g_strdup
|
||||
(" 'param 1 with spaces' \"param 2\" -a -b -cdef /path/to/file.txt +123");
|
||||
|
||||
/* when */
|
||||
execute_external_editor_or_viewer ("editor_or_viewer", filename_vpath, 123);
|
||||
|
||||
/* then */
|
||||
|
||||
/* check call to execute_get_external_cmd_opts_from_config() */
|
||||
g_assert_cmpstr (execute_external_cmd_opts__command__captured, ==, "editor_or_viewer");
|
||||
ck_assert_int_eq (vfs_path_cmp
|
||||
(execute_external_cmd_opts__filename_vpath__captured, filename_vpath), 0);
|
||||
ck_assert_int_eq (execute_external_cmd_opts__start_line__captured, 123);
|
||||
|
||||
/* check call to do_executev() */
|
||||
g_assert_cmpstr (do_executev__lc_shell__captured, ==, "editor_or_viewer");
|
||||
ck_assert_int_eq (do_executev__flags__captured, EXECUTE_INTERNAL);
|
||||
ck_assert_int_eq (do_executev__argv__captured->len, 7);
|
||||
|
||||
g_assert_cmpstr (g_ptr_array_index (do_executev__argv__captured, 0), ==, "param 1 with spaces");
|
||||
g_assert_cmpstr (g_ptr_array_index (do_executev__argv__captured, 1), ==, "param 2");
|
||||
g_assert_cmpstr (g_ptr_array_index (do_executev__argv__captured, 2), ==, "-a");
|
||||
g_assert_cmpstr (g_ptr_array_index (do_executev__argv__captured, 3), ==, "-b");
|
||||
g_assert_cmpstr (g_ptr_array_index (do_executev__argv__captured, 4), ==, "-cdef");
|
||||
g_assert_cmpstr (g_ptr_array_index (do_executev__argv__captured, 5), ==, "/path/to/file.txt");
|
||||
g_assert_cmpstr (g_ptr_array_index (do_executev__argv__captured, 6), ==, "+123");
|
||||
|
||||
vfs_path_free (filename_vpath);
|
||||
}
|
||||
/* *INDENT-OFF* */
|
||||
END_TEST
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int number_failed;
|
||||
|
||||
Suite *s = suite_create (TEST_SUITE_NAME);
|
||||
TCase *tc_core = tcase_create ("Core");
|
||||
SRunner *sr;
|
||||
|
||||
tcase_add_checked_fixture (tc_core, my_setup, my_teardown);
|
||||
|
||||
/* Add new tests here: *************** */
|
||||
tcase_add_test (tc_core, do_open_external_editor_or_viewer);
|
||||
/* *********************************** */
|
||||
|
||||
suite_add_tcase (s, tc_core);
|
||||
sr = srunner_create (s);
|
||||
srunner_set_log (sr, "execute__execute_external_editor_or_viewer.log");
|
||||
srunner_run_all (sr, CK_NORMAL);
|
||||
number_failed = srunner_ntests_failed (sr);
|
||||
srunner_free (sr);
|
||||
return (number_failed == 0) ? 0 : 1;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
Loading…
Reference in New Issue
Block a user