Updated Spanish translation
[anjuta-git-plugin.git] / plugins / project-wizard / install.c
blob3e5cfc4097b3df7fd34d9c36d7d4c9e6b4d347b9
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 install.c
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 *---------------------------------------------------------------------------*/
26 #include <config.h>
28 #include "install.h"
30 #include "plugin.h"
31 #include "file.h"
32 #include "parser.h"
33 #include "autogen.h"
34 #include "action.h"
36 #include <libanjuta/interfaces/ianjuta-file-loader.h>
37 #include <libanjuta/anjuta-launcher.h>
38 #include <libanjuta/anjuta-debug.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <sys/stat.h>
43 #include <sys/types.h>
44 #include <ctype.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 /*---------------------------------------------------------------------------*/
56 struct _NPWInstall
58 NPWAutogen* gen;
59 NPWFileListParser* parser;
60 NPWFileList* list;
61 const NPWFile* file;
62 NPWActionListParser* action_parser;
63 NPWActionList* action_list;
64 const NPWAction* action;
65 AnjutaLauncher* launcher;
66 NPWPlugin* plugin;
67 const gchar* project_file;
68 gboolean success;
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);
79 /* Helper functions
80 *---------------------------------------------------------------------------*/
82 static gboolean
83 npw_is_autogen_template_file (FILE* tpl)
85 gint len;
86 const gchar* marker[] = {"", AUTOGEN_MARKER_1, AUTOGEN_MARKER_2, NULL};
87 const gchar** key;
88 const gchar* ptr;
89 gint c;
92 for (key = marker; *key != NULL; ++key)
94 /* Skip first whitespace */
97 c = fgetc (tpl);
98 if (c == EOF) return FALSE;
100 while (isspace (c));
102 /* Test start marker, then autogen5, then template */
103 ptr = *key;
104 len = *ptr == '\0' ? AUTOGEN_START_MACRO_LEN : strlen (ptr);
107 if (len == 0) return FALSE;
108 --len;
109 if ((*ptr != '\0') && (tolower (c) != *ptr++)) return FALSE;
110 c = fgetc (tpl);
111 /* FIXME: Test this EOF test */
112 if (c == EOF) return FALSE;
114 while (!isspace (c));
115 if ((**key != '\0') && (len != 0)) return FALSE;
118 return TRUE;
121 static gboolean
122 npw_is_autogen_template (const gchar* filename)
124 FILE* tpl;
125 gboolean autogen;
127 tpl = fopen (filename, "rt");
128 if (tpl == NULL) return FALSE;
130 autogen = npw_is_autogen_template_file (tpl);
131 fclose (tpl);
133 return autogen;
136 static gboolean
137 npw_copy_file (const gchar* destination, const gchar* source)
139 gchar* buffer;
140 FILE* src;
141 FILE* dst;
142 guint len;
143 gboolean ok;
145 buffer = g_new (gchar, FILE_BUFFER_SIZE);
147 /* Copy file */
148 src = fopen (source, "rb");
149 if (src == NULL)
151 return FALSE;
154 dst = fopen (destination, "wb");
155 if (dst == NULL)
157 return FALSE;
160 ok = TRUE;
161 for (;!feof (src);)
163 len = fread (buffer, 1, FILE_BUFFER_SIZE, src);
164 if ((len != FILE_BUFFER_SIZE) && !feof (src))
166 ok = FALSE;
167 break;
170 if (len != fwrite (buffer, 1, len, dst))
172 ok = FALSE;
173 break;
177 fclose (dst);
178 fclose (src);
180 g_free (buffer);
182 return ok;
185 /* Installer object
186 *---------------------------------------------------------------------------*/
188 NPWInstall* npw_install_new (NPWPlugin* plugin)
190 NPWInstall* this;
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;
203 return 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;
231 g_free (this);
235 gboolean
236 npw_install_set_property (NPWInstall* this, NPWValueHeap* values)
238 npw_autogen_write_definition_file (this->gen, values);
240 return TRUE;
243 gboolean
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, "[+","+]");
260 return TRUE;
263 static void
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);
271 static void
272 on_install_end_action (gpointer data)
274 NPWInstall* this = (NPWInstall*)data;
276 for (;;)
278 if (this->action == NULL)
280 if (this->success)
282 /* Run action on success only */
283 this->action = npw_action_list_first (this->action_list);
286 else
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);
299 return;
301 switch (npw_action_get_type (this->action))
303 case NPW_RUN_ACTION:
304 npw_run_action (this);
305 return;
306 case NPW_OPEN_ACTION:
307 npw_open_action (this);
308 break;
309 default:
310 break;
315 static void
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);
325 static void
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);
333 static void
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);
340 this->file = 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);
349 static void
350 on_install_end_install_file (NPWAutogen* gen, gpointer data)
352 NPWInstall* this = (NPWInstall*)data;
354 /* Warning gen could be invalid */
356 for (;;)
358 if (this->file == NULL)
360 this->file = npw_file_list_first (this->list);
362 else
364 if (npw_file_get_execute (this->file))
366 gint previous;
367 /* Make this file executable */
368 previous = umask (0666);
369 chmod (npw_file_get_destination (this->file), 0777 & ~previous);
370 umask (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 */
383 if (this->success)
385 npw_plugin_print_view (this->plugin,
386 IANJUTA_MESSAGE_VIEW_TYPE_INFO,
387 _("New project has been created successfully"),
388 "");
390 else
392 npw_plugin_print_view (this->plugin,
393 IANJUTA_MESSAGE_VIEW_TYPE_ERROR,
394 _("New project creation has failed"),
395 "");
397 on_install_end_action (this);
399 return;
401 switch (npw_file_get_type (this->file))
403 case NPW_FILE:
404 npw_install_install_file (this);
405 return;
406 default:
407 g_warning("Unknown file type %d\n", npw_file_get_type (this->file));
408 break;
413 gboolean
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);
419 return TRUE;
422 static gboolean
423 npw_install_install_file (NPWInstall* this)
425 gchar* buffer;
426 gchar* sep;
427 guint len;
428 const gchar* destination;
429 const gchar* source;
430 gchar* msg;
431 gboolean use_autogen;
432 gboolean ok = TRUE;
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, "");
442 g_free (msg);
443 on_install_end_install_file (this->gen, this);
445 return FALSE;
448 /* Check if autogen is needed */
449 switch (npw_file_get_autogen (this->file))
451 case NPW_TRUE:
452 use_autogen = TRUE;
453 break;
454 case NPW_FALSE:
455 use_autogen = FALSE;
456 break;
457 case NPW_DEFAULT:
458 use_autogen = npw_is_autogen_template (source);
459 break;
460 default:
461 use_autogen = FALSE;
464 len = strlen (destination) + 1;
465 buffer = g_new (gchar, MAX (FILE_BUFFER_SIZE, len));
466 strcpy (buffer, destination);
467 sep = buffer;
468 for (;;)
470 /* Get directory one by one */
471 sep = strstr (sep,G_DIR_SEPARATOR_S);
472 if (sep == NULL) break;
473 /* Create directory if necessary */
474 *sep = '\0';
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);
482 ok = FALSE;
483 break;
487 *sep++ = G_DIR_SEPARATOR_S[0];
490 if (ok)
492 if (use_autogen)
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");
499 else
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 */
507 if (!ok)
509 this->success = FALSE;
511 npw_plugin_print_view (this->plugin, ok ? IANJUTA_MESSAGE_VIEW_TYPE_INFO : IANJUTA_MESSAGE_VIEW_TYPE_ERROR, msg, "");
512 g_free (msg);
514 /* Next file is called automatically if autogen succeed */
515 if (!ok || !use_autogen)
516 on_install_end_install_file (this->gen, this);
518 return ok;
521 static void
522 on_run_terminated (AnjutaLauncher* launcher, gint pid, gint status, gulong time, NPWInstall* this)
524 on_install_end_action (this);
527 static void
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);
535 static gboolean
536 npw_run_action (NPWInstall* this)
538 gchar *msg;
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);
549 static gboolean
550 npw_open_action (NPWInstall* this)
552 IAnjutaFileLoader* loader;
554 loader = anjuta_shell_get_interface (ANJUTA_PLUGIN (this->plugin)->shell, IAnjutaFileLoader, NULL);
555 if (loader)
557 ianjuta_file_loader_load (loader, npw_action_get_file (this->action), FALSE, NULL);
559 return TRUE;
562 return FALSE;