1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 Copyright (C) 2004 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * Handle installation of all files
24 *---------------------------------------------------------------------------*/
36 #include <libanjuta/interfaces/ianjuta-file-loader.h>
37 #include <libanjuta/anjuta-launcher.h>
38 #include <libanjuta/anjuta-debug.h>
43 #include <sys/types.h>
46 /*---------------------------------------------------------------------------*/
48 #define FILE_BUFFER_SIZE 4096
50 #define AUTOGEN_START_MACRO_LEN 7
51 #define AUTOGEN_MARKER_1 "autogen5"
52 #define AUTOGEN_MARKER_2 "template"
54 /*---------------------------------------------------------------------------*/
59 NPWFileListParser
* parser
;
62 NPWActionListParser
* action_parser
;
63 NPWActionList
* action_list
;
64 const NPWAction
* action
;
65 AnjutaLauncher
* launcher
;
67 const gchar
* project_file
;
71 /*---------------------------------------------------------------------------*/
73 static void on_install_end_install_file (NPWAutogen
* gen
, gpointer data
);
74 static void on_run_terminated (AnjutaLauncher
* launcher
, gint pid
, gint status
, gulong time
, NPWInstall
* this);
75 static gboolean
npw_install_install_file (NPWInstall
* this);
76 static gboolean
npw_run_action (NPWInstall
* this);
77 static gboolean
npw_open_action (NPWInstall
* this);
80 *---------------------------------------------------------------------------*/
83 npw_is_autogen_template_file (FILE* tpl
)
86 const gchar
* marker
[] = {"", AUTOGEN_MARKER_1
, AUTOGEN_MARKER_2
, NULL
};
92 for (key
= marker
; *key
!= NULL
; ++key
)
94 /* Skip first whitespace */
98 if (c
== EOF
) return FALSE
;
102 /* Test start marker, then autogen5, then template */
104 len
= *ptr
== '\0' ? AUTOGEN_START_MACRO_LEN
: strlen (ptr
);
107 if (len
== 0) return FALSE
;
109 if ((*ptr
!= '\0') && (tolower (c
) != *ptr
++)) return FALSE
;
111 /* FIXME: Test this EOF test */
112 if (c
== EOF
) return FALSE
;
114 while (!isspace (c
));
115 if ((**key
!= '\0') && (len
!= 0)) return FALSE
;
122 npw_is_autogen_template (const gchar
* filename
)
127 tpl
= fopen (filename
, "rt");
128 if (tpl
== NULL
) return FALSE
;
130 autogen
= npw_is_autogen_template_file (tpl
);
137 npw_copy_file (const gchar
* destination
, const gchar
* source
)
145 buffer
= g_new (gchar
, FILE_BUFFER_SIZE
);
148 src
= fopen (source
, "rb");
154 dst
= fopen (destination
, "wb");
163 len
= fread (buffer
, 1, FILE_BUFFER_SIZE
, src
);
164 if ((len
!= FILE_BUFFER_SIZE
) && !feof (src
))
170 if (len
!= fwrite (buffer
, 1, len
, dst
))
186 *---------------------------------------------------------------------------*/
188 NPWInstall
* npw_install_new (NPWPlugin
* plugin
)
192 /* Skip if already created */
193 if (plugin
->install
!= NULL
) return plugin
->install
;
195 this = g_new0(NPWInstall
, 1);
196 this->gen
= npw_autogen_new ();
197 this->plugin
= plugin
;
198 this->success
= TRUE
;
199 npw_plugin_create_view (plugin
);
201 plugin
->install
= this;
206 void npw_install_free (NPWInstall
* this)
208 if (this->parser
!= NULL
)
210 npw_file_list_parser_free (this->parser
);
212 if (this->list
!= NULL
)
214 npw_file_list_free (this->list
);
216 if (this->action_parser
!= NULL
)
218 npw_action_list_parser_free (this->action_parser
);
220 if (this->action_list
!= NULL
)
222 npw_action_list_free (this->action_list
);
224 if (this->launcher
!= NULL
)
226 g_signal_handlers_disconnect_by_func (G_OBJECT (this->launcher
), G_CALLBACK (on_run_terminated
), this);
227 g_object_unref (this->launcher
);
229 npw_autogen_free (this->gen
);
230 this->plugin
->install
= NULL
;
236 npw_install_set_property (NPWInstall
* this, NPWValueHeap
* values
)
238 npw_autogen_write_definition_file (this->gen
, values
);
244 npw_install_set_wizard_file (NPWInstall
* this, const gchar
* filename
)
246 if (this->list
!= NULL
)
248 npw_file_list_free (this->list
);
250 this->list
= npw_file_list_new ();
252 if (this->parser
!= NULL
)
254 npw_file_list_parser_free (this->parser
);
256 this->parser
= npw_file_list_parser_new (this->list
, filename
);
258 npw_autogen_set_input_file (this->gen
, filename
, "[+","+]");
264 on_install_read_action_list (const gchar
* output
, gpointer data
)
266 NPWInstall
* this = (NPWInstall
*)data
;
268 npw_action_list_parser_parse (this->action_parser
, output
, strlen (output
), NULL
);
272 on_install_end_action (gpointer data
)
274 NPWInstall
* this = (NPWInstall
*)data
;
278 if (this->action
== NULL
)
282 /* Run action on success only */
283 this->action
= npw_action_list_first (this->action_list
);
288 this->action
= npw_action_next (this->action
);
290 if (this->action
== NULL
)
292 DEBUG_PRINT ("Project wizard done");
293 /* The wizard could have been deactivated when loading the new
294 * project. Hence, the following check.
296 if (anjuta_plugin_is_active (ANJUTA_PLUGIN (this->plugin
)))
297 anjuta_plugin_deactivate (ANJUTA_PLUGIN (this->plugin
));
298 npw_install_free (this);
301 switch (npw_action_get_type (this->action
))
304 npw_run_action (this);
306 case NPW_OPEN_ACTION
:
307 npw_open_action (this);
316 on_install_read_all_action_list (NPWAutogen
* gen
, gpointer data
)
318 NPWInstall
* this = (NPWInstall
*)data
;
320 npw_action_list_parser_end_parse (this->action_parser
, NULL
);
322 on_install_end_install_file (NULL
, this);
326 on_install_read_file_list (const gchar
* output
, gpointer data
)
328 NPWInstall
* this = (NPWInstall
*)data
;
330 npw_file_list_parser_parse (this->parser
, output
, strlen (output
), NULL
);
334 on_install_read_all_file_list (NPWAutogen
* gen
, gpointer data
)
336 NPWInstall
* this = (NPWInstall
*)data
;
338 npw_file_list_parser_end_parse (this->parser
, NULL
);
341 this->project_file
= NULL
;
343 this->action_list
= npw_action_list_new ();
344 this->action_parser
= npw_action_list_parser_new (this->action_list
);
345 npw_autogen_set_output_callback (this->gen
, on_install_read_action_list
, this);
346 npw_autogen_execute (this->gen
, on_install_read_all_action_list
, this, NULL
);
350 on_install_end_install_file (NPWAutogen
* gen
, gpointer data
)
352 NPWInstall
* this = (NPWInstall
*)data
;
354 /* Warning gen could be invalid */
358 if (this->file
== NULL
)
360 this->file
= npw_file_list_first (this->list
);
364 if (npw_file_get_execute (this->file
))
367 /* Make this file executable */
368 previous
= umask (0666);
369 chmod (npw_file_get_destination (this->file
), 0777 & ~previous
);
372 if (npw_file_get_project (this->file
))
374 /* Check if project is NULL */
375 this->project_file
= npw_file_get_destination (this->file
);
377 this->file
= npw_file_next (this->file
);
379 if (this->file
== NULL
)
381 /* IAnjutaFileLoader* loader; */
382 /* All files have been installed */
385 npw_plugin_print_view (this->plugin
,
386 IANJUTA_MESSAGE_VIEW_TYPE_INFO
,
387 _("New project has been created successfully"),
392 npw_plugin_print_view (this->plugin
,
393 IANJUTA_MESSAGE_VIEW_TYPE_ERROR
,
394 _("New project creation has failed"),
397 on_install_end_action (this);
401 switch (npw_file_get_type (this->file
))
404 npw_install_install_file (this);
407 g_warning("Unknown file type %d\n", npw_file_get_type (this->file
));
414 npw_install_launch (NPWInstall
* this)
416 npw_autogen_set_output_callback (this->gen
, on_install_read_file_list
, this);
417 npw_autogen_execute (this->gen
, on_install_read_all_file_list
, this, NULL
);
423 npw_install_install_file (NPWInstall
* this)
428 const gchar
* destination
;
431 gboolean use_autogen
;
434 destination
= npw_file_get_destination (this->file
);
435 source
= npw_file_get_source (this->file
);
437 /* Check if file already exist */
438 if (g_file_test (destination
, G_FILE_TEST_EXISTS
))
440 msg
= g_strdup_printf (_("Skipping %s: file already exists"), destination
);
441 npw_plugin_print_view (this->plugin
, IANJUTA_MESSAGE_VIEW_TYPE_WARNING
, msg
, "");
443 on_install_end_install_file (this->gen
, this);
448 /* Check if autogen is needed */
449 switch (npw_file_get_autogen (this->file
))
458 use_autogen
= npw_is_autogen_template (source
);
464 len
= strlen (destination
) + 1;
465 buffer
= g_new (gchar
, MAX (FILE_BUFFER_SIZE
, len
));
466 strcpy (buffer
, destination
);
470 /* Get directory one by one */
471 sep
= strstr (sep
,G_DIR_SEPARATOR_S
);
472 if (sep
== NULL
) break;
473 /* Create directory if necessary */
475 if ((*buffer
!= '~') && (*buffer
!= '\0'))
477 if (!g_file_test (buffer
, G_FILE_TEST_EXISTS
))
479 if (mkdir (buffer
, 0755) == -1)
481 msg
= g_strdup_printf (_("Creating %s ... Fail to create directory"), destination
);
487 *sep
++ = G_DIR_SEPARATOR_S
[0];
494 npw_autogen_set_input_file (this->gen
, source
, NULL
, NULL
);
495 npw_autogen_set_output_file (this->gen
, destination
);
496 ok
= npw_autogen_execute (this->gen
, on_install_end_install_file
, this, NULL
);
497 msg
= g_strdup_printf (_("Creating %s (using AutoGen)... %s"), destination
, ok
? "Ok" : "Fail to Execute");
501 ok
= npw_copy_file (destination
, source
);
502 msg
= g_strdup_printf (_("Creating %s ... %s"), destination
, ok
? "Ok" : "Fail to copy file");
506 /* Record failure and display error message */
509 this->success
= FALSE
;
511 npw_plugin_print_view (this->plugin
, ok
? IANJUTA_MESSAGE_VIEW_TYPE_INFO
: IANJUTA_MESSAGE_VIEW_TYPE_ERROR
, msg
, "");
514 /* Next file is called automatically if autogen succeed */
515 if (!ok
|| !use_autogen
)
516 on_install_end_install_file (this->gen
, this);
522 on_run_terminated (AnjutaLauncher
* launcher
, gint pid
, gint status
, gulong time
, NPWInstall
* this)
524 on_install_end_action (this);
528 on_run_output (AnjutaLauncher
* launcher
, AnjutaLauncherOutputType type
, const gchar
* output
, gpointer data
)
530 NPWInstall
* this = (NPWInstall
*)data
;
532 npw_plugin_append_view (this->plugin
, output
);
536 npw_run_action (NPWInstall
* this)
539 if (this->launcher
== NULL
)
541 this->launcher
= anjuta_launcher_new ();
543 g_signal_connect (G_OBJECT (this->launcher
), "child-exited", G_CALLBACK (on_run_terminated
), this);
544 msg
= g_strconcat (_("Executing: "), npw_action_get_command (this->action
), NULL
);
545 npw_plugin_print_view (this->plugin
, IANJUTA_MESSAGE_VIEW_TYPE_INFO
, msg
, "");
546 return anjuta_launcher_execute (this->launcher
, npw_action_get_command (this->action
), on_run_output
, this);
550 npw_open_action (NPWInstall
* this)
552 IAnjutaFileLoader
* loader
;
554 loader
= anjuta_shell_get_interface (ANJUTA_PLUGIN (this->plugin
)->shell
, IAnjutaFileLoader
, NULL
);
557 ianjuta_file_loader_load (loader
, npw_action_get_file (this->action
), FALSE
, NULL
);