1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 Copyright (C) 2005 Sebastien Granjoux
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 * Execute an external tool
24 *---------------------------------------------------------------------------*/
32 #include <libanjuta/anjuta-utils.h>
33 #include <libanjuta/interfaces/ianjuta-document-manager.h>
34 #include <libanjuta/interfaces/ianjuta-editor.h>
35 #include <libanjuta/interfaces/ianjuta-editor-selection.h>
36 #include <libanjuta/interfaces/ianjuta-file-savable.h>
37 #include <libanjuta/interfaces/ianjuta-file-loader.h>
43 /*---------------------------------------------------------------------------*/
45 #define ICON_FILE "anjuta-tools-plugin.png"
46 #define MAX_TOOL_PANES 4
48 /* Widget and signal name found in glade file
49 *---------------------------------------------------------------------------*/
51 #define TOOL_PARAMS "param_dialog"
52 #define TOOL_PARAMS_EN "tool.params"
53 #define TOOL_PARAMS_EN_COMBO "tool.params.combo"
55 /*---------------------------------------------------------------------------*/
58 * Allow to have common code for handling stderr and stdout but it includes
59 * some part checking if this is used to implement stderr or stdout. So, It
60 * is strongly linked to ATPExecutionContext.
65 struct _ATPExecutionContext
* execution
;
66 IAnjutaMessageView
* view
;
69 IAnjutaEditor
* editor
;
73 /* Execute information
74 * This is filled at the beginning with all necessary tool information,
75 * so it becomes independent from the tool after creation. It includes
76 * two OutputContext (one for stderr and one for stdout). The context
77 * is not destroyed when the tool execution terminate, so it can be
78 * reuse later for another tool. It useful mainly for keeping pointer
79 * on created message panes. All the tool context are kept in a list. */
80 typedef struct _ATPExecutionContext
83 gchar
* directory
; // used for opening file from message pane
84 ATPOutputContext output
;
85 ATPOutputContext error
;
87 AnjutaLauncher
*launcher
;
89 } ATPExecutionContext
;
92 *---------------------------------------------------------------------------*/
94 /* Save all current anjuta files */
96 save_all_files (AnjutaPlugin
*plugin
)
98 IAnjutaDocumentManager
*docman
;
99 IAnjutaFileSavable
* save
;
101 docman
= anjuta_shell_get_interface (plugin
->shell
, IAnjutaDocumentManager
, NULL
);
102 /* No document manager, so no file to save */
105 save
= IANJUTA_FILE_SAVABLE (docman
);
106 if (save
) ianjuta_file_savable_save (save
, NULL
);
110 /* Replace variable in source and add prefix separated with a space */
112 replace_variable (const gchar
* prefix
, const gchar
* source
,
113 ATPVariable
* variable
)
119 /* Create string and add prefix */
120 str
= g_string_new (prefix
);
123 g_string_append_c (str
, ' ');
126 /* Add source and replace variable */
129 for (; *source
!= '\0'; source
+= len
)
131 if (source
[0] != '$')
133 /* Just append anything that doesn't looks like a variable */
134 for (len
= 0; (source
[len
] != '\0') &&
135 (source
[len
] != '$'); len
++);
136 g_string_append_len (str
, source
, len
);
138 else if (source
[1] != '(')
140 g_string_append_c (str
, '$');
145 /* Check if there is a variable */
146 for (len
= 2; g_ascii_isalnum(source
[len
])
147 || (source
[len
] == '_') ; len
++);
148 if (source
[len
] == ')')
151 val
= atp_variable_get_value_from_name_part (variable
, source
+ 2, len
- 3);
154 /* This is really a variable, replace */
155 g_string_append (str
, val
);
160 /* It's not a variable */
161 g_string_append_len (str
, source
, len
);
166 /* Remove leading space, trailing space and empty string */
167 val
= g_string_free (str
, FALSE
);
171 if ((val
!= NULL
) && (*val
== '\0'))
182 parse_error_line (const gchar
* line
, gchar
** filename
, int *lineno
)
189 while (line
[i
++] != ':')
191 if (i
>= strlen (line
) || i
>= 512 || line
[i
- 1] == ' ')
196 if (isdigit (line
[i
]))
199 while (isdigit (line
[i
++])) ;
200 dummy
= g_strndup (&line
[j
], i
- j
- 1);
201 *lineno
= atoi (dummy
);
204 dummy
= g_strndup (line
, j
- 1);
205 *filename
= g_strdup (g_strstrip (dummy
));
212 i
= strlen (line
) - 1;
213 while (isspace (line
[i
]) == FALSE
)
224 while (line
[i
++] != ':')
226 if (i
>= strlen (line
) || i
>= 512 || line
[i
- 1] == ' ')
233 if (isdigit (line
[i
]))
236 while (isdigit (line
[i
++])) ;
237 dummy
= g_strndup (&line
[j
], i
- j
- 1);
238 *lineno
= atoi (dummy
);
241 dummy
= g_strndup (&line
[k
], j
- k
- 1);
242 *filename
= g_strdup (g_strstrip (dummy
));
252 /* Output context functions
253 *---------------------------------------------------------------------------*/
256 on_message_buffer_click (IAnjutaMessageView
*view
, const gchar
*line
,
257 ATPOutputContext
*this)
262 if (parse_error_line (line
, &filename
, &lineno
))
265 IAnjutaFileLoader
*loader
;
267 /* Go to file and line number */
268 loader
= anjuta_shell_get_interface (this->execution
->plugin
->shell
,
272 /* Append current directory */
273 if ((this->execution
->directory
!= NULL
) &&
274 (*filename
!= G_DIR_SEPARATOR
))
276 if (*filename
== '.')
278 uri
= g_strdup_printf ("file://%s/%s#%d",
279 this->execution
->directory
,
280 filename
+ 1, lineno
);
284 uri
= g_strdup_printf ("file://%s/%s#%d",
285 this->execution
->directory
,
291 uri
= g_strdup_printf ("file:///%s#%d", filename
, lineno
);
294 ianjuta_file_loader_load (loader
, uri
, FALSE
, NULL
);
300 on_message_buffer_flush (IAnjutaMessageView
*view
, const gchar
*msg_line
,
301 ATPOutputContext
*this)
306 IAnjutaMessageViewType type
;
308 /* If there is a gdb style annotation to open a file, open it */
309 if (strlen(msg_line
) > 2 && msg_line
[0] == '\032' &&
310 msg_line
[1] == '\032')
312 line
= g_strdup_printf (_("Opening %s"), &msg_line
[2]);
313 on_message_buffer_click (view
, &msg_line
[2], this);
317 line
= g_strdup (msg_line
);
324 type
= IANJUTA_MESSAGE_VIEW_TYPE_NORMAL
;
325 if (parse_error_line(line
, &dummy_fn
, &dummy_int
))
328 if ((strstr (line
, _("warning:")) != NULL
) ||
329 (strstr (line
, "warning:") != NULL
))
331 type
= IANJUTA_MESSAGE_VIEW_TYPE_WARNING
;
333 else if ((strstr (line
, _("error:")) != NULL
) ||
334 (strstr (line
, "error:") != NULL
))
336 type
= IANJUTA_MESSAGE_VIEW_TYPE_ERROR
;
340 else if (strstr (line
, ":") != NULL
)
342 type
= IANJUTA_MESSAGE_VIEW_TYPE_INFO
;
344 ianjuta_message_view_append (this->view
, type
, line
, desc
, NULL
);
349 /* Handle output for stdout and stderr */
351 atp_output_context_print (ATPOutputContext
*this, const gchar
* text
)
355 if (this->type
== ATP_TOUT_SAME
)
357 /* Valid for error output only, get output type
358 * from standard output */
359 this = &this->execution
->output
;
365 /* output should not use this */
366 g_return_val_if_reached (TRUE
);
370 case ATP_TOUT_COMMON_PANE
:
371 case ATP_TOUT_NEW_PANE
:
372 /* Check if the view has already been created */
373 if (this->created
== FALSE
)
375 IAnjutaMessageManager
*man
;
376 gchar
* title
= this->execution
->name
;
378 man
= anjuta_shell_get_interface (this->execution
->plugin
->shell
,
379 IAnjutaMessageManager
, NULL
);
380 if (this->view
== NULL
)
382 this->view
= ianjuta_message_manager_add_view (man
, title
,
385 g_signal_connect (G_OBJECT (this->view
), "buffer_flushed",
386 G_CALLBACK (on_message_buffer_flush
), this);
387 g_signal_connect (G_OBJECT (this->view
), "message_clicked",
388 G_CALLBACK (on_message_buffer_click
), this);
389 g_object_add_weak_pointer (G_OBJECT (this->view
),
390 (gpointer
*)(gpointer
)&this->view
);
394 ianjuta_message_view_clear (this->view
, NULL
);
396 if (this->execution
->error
.type
== ATP_TOUT_SAME
)
398 /* Same message used for all outputs */
401 else if (this == &this->execution
->output
)
403 /* Only for output data */
408 /* Only for error data */
411 title
= g_strdup_printf ("%s %s", this->execution
->name
, str
);
413 ianjuta_message_manager_set_view_title (man
, this->view
,
416 this->created
= TRUE
;
418 /* Display message */
421 ianjuta_message_view_buffer_append (this->view
, text
, NULL
);
424 case ATP_TOUT_NEW_BUFFER
:
425 case ATP_TOUT_REPLACE_BUFFER
:
428 ianjuta_editor_append (this->editor
, text
, strlen(text
), NULL
);
431 case ATP_TOUT_INSERT_BUFFER
:
432 case ATP_TOUT_APPEND_BUFFER
:
433 case ATP_TOUT_REPLACE_SELECTION
:
434 case ATP_TOUT_POPUP_DIALOG
:
435 g_string_append (this->buffer
, text
);
437 case ATP_TOUT_UNKNOWN
:
438 case ATP_OUTPUT_TYPE_COUNT
:
439 g_return_val_if_reached (TRUE
);
445 /* Write a small message at the beginning use only on stdout */
447 atp_output_context_print_command (ATPOutputContext
*this, const gchar
* command
)
457 case ATP_TOUT_COMMON_PANE
:
458 case ATP_TOUT_NEW_PANE
:
460 ok
= atp_output_context_print (this, _("Running command: "));
461 ok
&= atp_output_context_print (this, command
);
462 ok
&= atp_output_context_print (this, "...\n");
464 case ATP_TOUT_NEW_BUFFER
:
465 case ATP_TOUT_REPLACE_BUFFER
:
466 case ATP_TOUT_INSERT_BUFFER
:
467 case ATP_TOUT_APPEND_BUFFER
:
468 case ATP_TOUT_REPLACE_SELECTION
:
469 case ATP_TOUT_POPUP_DIALOG
:
470 /* Do nothing for all these cases */
472 case ATP_TOUT_UNKNOWN
:
473 case ATP_OUTPUT_TYPE_COUNT
:
474 g_return_val_if_reached (TRUE
);
480 /* Call at the end for stdout and stderr */
482 atp_output_context_print_result (ATPOutputContext
*this, gint error
)
486 IAnjutaMessageManager
*man
;
494 case ATP_TOUT_COMMON_PANE
:
495 case ATP_TOUT_NEW_PANE
:
496 if (this == &this->execution
->output
)
500 ok
= atp_output_context_print (this, _("Completed... unsuccessful with "));
501 sprintf (buffer
, "%d", error
);
502 ok
&= atp_output_context_print (this, buffer
);
506 ok
= atp_output_context_print (this, _("Completed... successful"));
508 ok
&= atp_output_context_print (this, "\n");
511 man
= anjuta_shell_get_interface (this->execution
->plugin
->shell
,
512 IAnjutaMessageManager
, NULL
);
513 ianjuta_message_manager_set_current_view (man
, this->view
, NULL
);
518 case ATP_TOUT_NEW_BUFFER
:
519 case ATP_TOUT_REPLACE_BUFFER
:
522 case ATP_TOUT_INSERT_BUFFER
:
525 ianjuta_editor_insert (this->editor
, this->position
, this->buffer
->str
,
526 this->buffer
->len
, NULL
);
528 g_string_free (this->buffer
, TRUE
);
531 case ATP_TOUT_APPEND_BUFFER
:
534 ianjuta_editor_append (this->editor
, this->buffer
->str
,
535 this->buffer
->len
, NULL
);
537 g_string_free (this->buffer
, TRUE
);
540 case ATP_TOUT_REPLACE_SELECTION
:
543 ianjuta_editor_selection_replace (IANJUTA_EDITOR_SELECTION (this->editor
),
545 this->buffer
->len
, NULL
);
547 g_string_free (this->buffer
, TRUE
);
550 case ATP_TOUT_POPUP_DIALOG
:
551 if (this->buffer
->len
)
553 if (this == &this->execution
->output
)
555 anjuta_util_dialog_info (GTK_WINDOW (this->execution
->plugin
->shell
),
560 anjuta_util_dialog_error (GTK_WINDOW (this->execution
->plugin
->shell
),
563 g_string_free (this->buffer
, TRUE
);
567 case ATP_TOUT_UNKNOWN
:
568 case ATP_OUTPUT_TYPE_COUNT
:
569 g_return_val_if_reached (TRUE
);
575 static IAnjutaEditor
*
576 get_current_editor(IAnjutaDocumentManager
* docman
)
580 IAnjutaDocument
* doc
= ianjuta_document_manager_get_current_document(docman
, NULL
);
581 if (doc
&& IANJUTA_IS_EDITOR(doc
))
582 return IANJUTA_EDITOR(doc
);
587 static ATPOutputContext
*
588 atp_output_context_initialize (ATPOutputContext
*this,
589 ATPExecutionContext
*execution
,
592 IAnjutaDocumentManager
*docman
;
600 case ATP_TOUT_COMMON_PANE
:
601 case ATP_TOUT_NEW_PANE
:
602 this->created
= FALSE
;
604 case ATP_TOUT_REPLACE_BUFFER
:
605 docman
= anjuta_shell_get_interface (ANJUTA_PLUGIN (this->execution
->plugin
)->shell
, IAnjutaDocumentManager
, NULL
);
606 this->editor
= get_current_editor(docman
);
607 if (this->editor
!= NULL
)
609 g_object_add_weak_pointer (G_OBJECT (this->editor
), (gpointer
*)(gpointer
)&this->editor
);
610 ianjuta_editor_erase_all (this->editor
, NULL
);
613 /* Go through, try to create a new buffer */
614 case ATP_TOUT_NEW_BUFFER
:
615 docman
= anjuta_shell_get_interface (ANJUTA_PLUGIN (this->execution
->plugin
)->shell
, IAnjutaDocumentManager
, NULL
);
616 this->editor
= get_current_editor(docman
);
617 if (this->editor
== NULL
)
619 anjuta_util_dialog_warning (GTK_WINDOW (this->execution
->plugin
->shell
), _("Unable to create a buffer, command aborted"));
622 g_object_add_weak_pointer (G_OBJECT (this->editor
), (gpointer
*)(gpointer
)&this->editor
);
624 case ATP_TOUT_INSERT_BUFFER
:
625 case ATP_TOUT_APPEND_BUFFER
:
626 case ATP_TOUT_REPLACE_SELECTION
:
627 docman
= anjuta_shell_get_interface (ANJUTA_PLUGIN (this->execution
->plugin
)->shell
, IAnjutaDocumentManager
, NULL
);
628 this->editor
= docman
== NULL
? NULL
: IANJUTA_EDITOR( ianjuta_document_manager_get_current_document (docman
, NULL
));
629 if (this->editor
== NULL
)
631 anjuta_util_dialog_warning (GTK_WINDOW (this->execution
->plugin
->shell
), _("No document currently open, command aborted"));
634 g_object_add_weak_pointer (G_OBJECT (this->editor
), (gpointer
*)(gpointer
)&this->editor
);
635 this->position
= ianjuta_editor_get_position (this->editor
, NULL
);
636 /* No break, need a buffer too */
637 case ATP_TOUT_POPUP_DIALOG
:
638 if (this->buffer
== NULL
)
640 this->buffer
= g_string_new ("");
644 g_string_erase (this->buffer
, 0, -1);
647 case ATP_TOUT_UNKNOWN
:
648 case ATP_OUTPUT_TYPE_COUNT
:
649 g_return_val_if_reached (this);
656 static ATPOutputContext
*
657 atp_output_context_construct (ATPOutputContext
*this,
658 ATPExecutionContext
*execution
,
662 this->execution
= execution
;
666 return atp_output_context_initialize (this, execution
, type
);
670 atp_output_context_destroy (ATPOutputContext
*this)
674 IAnjutaMessageManager
*man
;
676 man
= anjuta_shell_get_interface (this->execution
->plugin
->shell
,
677 IAnjutaMessageManager
, NULL
);
678 ianjuta_message_manager_remove_view (man
, this->view
, NULL
);
683 g_string_free (this->buffer
, TRUE
);
688 *---------------------------------------------------------------------------*/
691 on_run_terminated (AnjutaLauncher
* launcher
, gint pid
, gint status
,
692 gulong time
, gpointer user_data
)
694 ATPExecutionContext
*this = (ATPExecutionContext
*)user_data
;
696 atp_output_context_print_result (&this->output
, status
);
697 atp_output_context_print_result (&this->error
, status
);
702 on_run_output (AnjutaLauncher
* launcher
, AnjutaLauncherOutputType type
,
703 const gchar
* output
, gpointer user_data
)
705 ATPExecutionContext
* this = (ATPExecutionContext
*)user_data
;
709 case ANJUTA_LAUNCHER_OUTPUT_STDOUT
:
710 atp_output_context_print (&this->output
, output
);
712 case ANJUTA_LAUNCHER_OUTPUT_STDERR
:
713 atp_output_context_print (&this->error
, output
);
715 case ANJUTA_LAUNCHER_OUTPUT_PTY
:
720 static ATPExecutionContext
*
721 atp_execution_context_reuse (ATPExecutionContext
* this, const gchar
*name
,
722 ATPOutputType output
, ATPOutputType error
)
724 if (this->name
) g_free (this->name
);
725 this->name
= atp_remove_mnemonic (name
);
727 if (atp_output_context_initialize (&this->output
, this, output
) == NULL
)
731 if (atp_output_context_initialize (&this->error
, this, error
) == NULL
)
739 static ATPExecutionContext
*
740 atp_execution_context_new (AnjutaPlugin
*plugin
, const gchar
*name
,
741 guint id
, ATPOutputType output
, ATPOutputType error
)
743 ATPExecutionContext
*this;
745 this = g_new0 (ATPExecutionContext
, 1);
747 this->plugin
= plugin
;
748 this->launcher
= anjuta_launcher_new ();
749 g_signal_connect (G_OBJECT (this->launcher
), "child-exited",
750 G_CALLBACK (on_run_terminated
), this);
751 this->name
= atp_remove_mnemonic (name
);
753 if (atp_output_context_construct (&this->output
, this, output
) == NULL
)
758 if (atp_output_context_construct (&this->error
, this, error
) == NULL
)
768 atp_execution_context_free (ATPExecutionContext
* this)
770 atp_output_context_destroy (&this->output
);
771 atp_output_context_destroy (&this->error
);
775 g_object_unref (this->launcher
);
777 if (this->name
) g_free (this->name
);
778 if (this->directory
) g_free (this->directory
);
784 atp_execution_context_set_directory (ATPExecutionContext
* this,
785 const gchar
* directory
)
787 if (this->directory
!= NULL
) g_free (this->directory
);
788 this->directory
= directory
== NULL
? NULL
: g_strdup (directory
);
792 atp_execution_context_execute (ATPExecutionContext
* this,
793 const gchar
* command
, const gchar
* input
)
795 gchar
* prev_dir
= NULL
;
797 atp_output_context_print_command (&this->output
, command
);
799 /* Change working directory */
800 if (this->directory
!= NULL
)
802 prev_dir
= g_get_current_dir();
803 chdir (this->directory
);
806 anjuta_launcher_execute (this->launcher
, command
, on_run_output
, this);
807 /* Restore previous current directory */
808 if (this->directory
!= NULL
)
813 anjuta_launcher_set_encoding (this->launcher
, NULL
);
816 /* Send stdin data if needed */
819 anjuta_launcher_send_stdin (this->launcher
, input
);
820 /* Send end marker */
821 anjuta_launcher_send_stdin (this->launcher
, "\x04");
825 /* Execute context list
826 *---------------------------------------------------------------------------*/
829 atp_context_list_construct (ATPContextList
*this)
836 atp_context_list_destroy (ATPContextList
*this)
840 for (item
= this->list
; item
!= NULL
; item
= this->list
)
842 this->list
= g_list_remove_link (this->list
, item
);
843 atp_execution_context_free ((ATPExecutionContext
*)item
->data
);
848 static ATPExecutionContext
*
849 atp_context_list_find_context (ATPContextList
*this, AnjutaPlugin
*plugin
,
850 const gchar
* name
, ATPOutputType output
,
853 ATPExecutionContext
* context
;
859 gboolean output_pane
;
865 new_pane
= (output
== ATP_TOUT_NEW_PANE
) || (error
== ATP_TOUT_NEW_PANE
);
866 output_pane
= (output
== ATP_TOUT_NEW_PANE
) || (output
== ATP_TOUT_COMMON_PANE
);
867 error_pane
= (error
== ATP_TOUT_NEW_PANE
) || (error
== ATP_TOUT_COMMON_PANE
);
868 for (node
= this->list
; node
!= NULL
; node
= g_list_next (node
))
870 ATPExecutionContext
* current
;
873 current
= (ATPExecutionContext
*)node
->data
;
875 /* Count number of used message panes */
876 if (current
->output
.view
!= NULL
) pane
++;
877 if (current
->error
.view
!= NULL
) pane
++;
880 if ((current
->output
.view
!= NULL
) == output_pane
) score
++;
881 if ((current
->error
.view
!= NULL
) == error_pane
) score
++;
885 if ((score
> best
) || ((score
== best
) && (new_pane
)))
887 /* Reuse this context */
895 if ((new_pane
) && (pane
< MAX_TOOL_PANES
))
897 /* Not too many message pane, we can create a new one */
903 /* Create a new node */
904 context
= atp_execution_context_new (plugin
, name
, 0, output
, error
);
907 this->list
= g_list_prepend (this->list
, context
);
912 this->list
= g_list_remove_link (this->list
, reuse
);
913 context
= atp_execution_context_reuse (context
, name
, output
, error
);
916 this->list
= g_list_concat (reuse
, this->list
);
924 *---------------------------------------------------------------------------*/
926 /* Menu activate handler which executes the tool. It should do command
927 ** substitution, input, output and error redirection, setting the
928 ** working directory, etc.
931 atp_user_tool_execute (GtkMenuItem
*item
, ATPUserTool
* this)
934 ATPVariable
* variable
;
935 ATPContextList
* list
;
936 ATPExecutionContext
* context
;
937 IAnjutaDocumentManager
*docman
;
944 plugin
= atp_user_tool_get_plugin (this);
945 variable
= atp_plugin_get_variable (plugin
);
947 /* Save files if requested */
948 if (atp_user_tool_get_flag (this, ATP_TOOL_AUTOSAVE
))
950 save_all_files (ANJUTA_PLUGIN (plugin
));
953 /* Make command line */
954 cmd
= replace_variable (atp_user_tool_get_command (this),
955 atp_user_tool_get_param (this), variable
);
957 /* Get working directory and replace variable */
958 dir
= replace_variable (NULL
, atp_user_tool_get_working_dir (this),
961 if (atp_user_tool_get_flag (this, ATP_TOOL_TERMINAL
))
963 /* Run in a terminal */
964 /* don't need a execution context, launch and forget */
966 gnome_execute_terminal_shell (dir
, cmd
);
970 /* Get stdin if necessary */
972 switch (atp_user_tool_get_input (this))
975 docman
= anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin
)->shell
,
976 IAnjutaDocumentManager
, NULL
);
977 ed
= get_current_editor(docman
);
980 input
= ianjuta_editor_get_text (ed
, 0, -1, NULL
);
983 case ATP_TIN_SELECTION
:
984 docman
= anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin
)->shell
,
985 IAnjutaDocumentManager
, NULL
);
986 ed
= get_current_editor(docman
);
989 input
= ianjuta_editor_selection_get (IANJUTA_EDITOR_SELECTION (ed
),
994 input
= replace_variable (NULL
,
995 atp_user_tool_get_input_string (this),
999 val
= replace_variable (NULL
, atp_user_tool_get_input_string (this),
1001 if ((val
== NULL
) || (!g_file_get_contents (val
, &input
, NULL
, NULL
)))
1003 anjuta_util_dialog_error (atp_plugin_get_app_window (plugin
),
1004 _("Unable to open input file %s, Command aborted"), val
== NULL
? "(null)" : val
);
1005 if (val
!= NULL
) g_free (val
);
1006 if (dir
!= NULL
) g_free (dir
);
1007 if (cmd
!= NULL
) g_free (cmd
);
1017 list
= atp_plugin_get_context_list (plugin
);
1019 context
= atp_context_list_find_context (list
, ANJUTA_PLUGIN(plugin
),
1020 atp_user_tool_get_name (this),
1021 atp_user_tool_get_output (this),
1022 atp_user_tool_get_error (this));
1026 /* Set working directory */
1027 atp_execution_context_set_directory (context
, dir
);
1030 atp_execution_context_execute (context
, cmd
, input
);
1033 if (input
!= NULL
) g_free(input
);
1036 if (dir
!= NULL
) g_free (dir
);
1037 if (cmd
!= NULL
) g_free (cmd
);