1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
2 /* am-package.c
3 *
4 * Copyright (C) 2009 Sébastien Granjoux
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
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 GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include "amp-package.h"
28
29 #include "amp-node.h"
30 #include "am-scanner.h"
31 #include "am-properties.h"
32 #include "ac-writer.h"
33
34
35 #include <libanjuta/interfaces/ianjuta-project.h>
36 #include <libanjuta/anjuta-utils.h>
37 #include <libanjuta/anjuta-pkg-config.h>
38
39 #include <libanjuta/anjuta-debug.h>
40
41 #include <glib/gi18n.h>
42
43 #include <memory.h>
44 #include <string.h>
45 #include <ctype.h>
46
47 /* Types
48 *---------------------------------------------------------------------------*/
49
50 struct _AmpPackageNode {
51 AnjutaProjectNode base;
52 gchar *version;
53 AnjutaToken *token;
54 };
55
56 typedef struct _AmpPackageNodeClass AmpPackageNodeClass;
57
58 struct _AmpPackageNodeClass {
59 AmpNodeClass parent_class;
60 };
61
62 G_DEFINE_DYNAMIC_TYPE (AmpPackageNode, amp_package_node, AMP_TYPE_NODE);
63
64
65 /* Package objects
66 *---------------------------------------------------------------------------*/
67
68 AmpPackageNode*
amp_package_node_new(const gchar * name)69 amp_package_node_new (const gchar *name)
70 {
71 AmpPackageNode *node = NULL;
72
73 node = g_object_new (AMP_TYPE_PACKAGE_NODE, NULL);
74 node->base.name = g_strdup (name);
75
76 return node;
77 }
78
79 AmpPackageNode*
amp_package_node_new_valid(const gchar * name,GError ** error)80 amp_package_node_new_valid (const gchar *name, GError **error)
81 {
82 return amp_package_node_new (name);
83 }
84
85 void
amp_package_node_free(AmpPackageNode * node)86 amp_package_node_free (AmpPackageNode *node)
87 {
88 g_object_unref (G_OBJECT (node));
89 }
90
91 void
amp_package_node_set_version(AmpPackageNode * node,const gchar * compare,const gchar * version)92 amp_package_node_set_version (AmpPackageNode *node, const gchar *compare, const gchar *version)
93 {
94 g_return_if_fail (node != NULL);
95 g_return_if_fail ((version == NULL) || (compare != NULL));
96
97 g_free (node->version);
98 node->version = version != NULL ? g_strconcat (compare, version, NULL) : NULL;
99 }
100
101 AnjutaToken *
amp_package_node_get_token(AmpPackageNode * node)102 amp_package_node_get_token (AmpPackageNode *node)
103 {
104 return node->token;
105 }
106
107 void
amp_package_node_add_token(AmpPackageNode * node,AnjutaToken * token)108 amp_package_node_add_token (AmpPackageNode *node, AnjutaToken *token)
109 {
110 node->token = token;
111 }
112
113 void
amp_package_node_update_node(AmpPackageNode * node,AmpPackageNode * new_node)114 amp_package_node_update_node (AmpPackageNode *node, AmpPackageNode *new_node)
115 {
116 g_return_if_fail (new_node != NULL);
117
118 node->token = new_node->token;
119 g_free (node->version);
120 node->version = new_node->version;
121 new_node->version = NULL;
122 }
123
124 /* AmpNode implementation
125 *---------------------------------------------------------------------------*/
126
127 static gboolean
amp_package_node_load(AmpNode * node,AmpNode * parent,AmpProject * project,GError ** error)128 amp_package_node_load (AmpNode *node, AmpNode *parent, AmpProject *project, GError **error)
129 {
130 GList* deps;
131 GList* dep;
132 GList* include_dirs = NULL;
133
134 deps = anjuta_pkg_config_list_dependencies (anjuta_project_node_get_name (ANJUTA_PROJECT_NODE (node)),
135 error);
136 for (dep = deps; dep != NULL; dep = g_list_next (dep))
137 {
138 /* Create a package node for the depedencies */
139 AnjutaProjectNode *pkg;
140
141 pkg = ANJUTA_PROJECT_NODE (amp_package_node_new (dep->data));
142 anjuta_project_node_append (ANJUTA_PROJECT_NODE (node), pkg);
143 }
144 anjuta_util_glist_strings_free (deps);
145
146 if (*error != NULL)
147 {
148 g_warning ("Error getting dependencies: %s", (*error)->message);
149 g_error_free (*error);
150 *error = NULL;
151 }
152
153 if ((include_dirs = anjuta_pkg_config_get_directories (anjuta_project_node_get_name (ANJUTA_PROJECT_NODE (node)),
154 TRUE, error)))
155 {
156 GList* include_dir;
157
158 for (include_dir = include_dirs; include_dir != NULL; include_dir = g_list_next (include_dir))
159 {
160 GList* children = NULL;
161 GList* file = NULL;
162 GFile* dir = g_file_new_for_path (include_dir->data);
163
164 anjuta_util_list_all_dir_children (&children, dir);
165 for (file = g_list_first (children); file != NULL; file = g_list_next (file))
166 {
167 /* Create a source for files */
168 AnjutaProjectNode *source;
169
170 source = amp_node_new_valid (ANJUTA_PROJECT_NODE (parent), ANJUTA_PROJECT_SOURCE, (GFile *)file->data, NULL, NULL);
171 anjuta_project_node_append (ANJUTA_PROJECT_NODE (node), source);
172 g_object_unref ((GObject *)file->data);
173 }
174 g_list_free (children);
175 g_object_unref (dir);
176 }
177 }
178 anjuta_util_glist_strings_free (include_dirs);
179
180 return TRUE;
181 }
182
183 static gboolean
amp_package_node_update(AmpNode * node,AmpNode * new_node)184 amp_package_node_update (AmpNode *node, AmpNode *new_node)
185 {
186 amp_package_node_update_node (AMP_PACKAGE_NODE (node), AMP_PACKAGE_NODE (new_node));
187
188 return TRUE;
189 }
190
191 static AmpNode *
amp_package_node_copy(AmpNode * old_node)192 amp_package_node_copy (AmpNode *old_node)
193 {
194 AmpNode *new_node;
195
196 new_node = AMP_NODE_CLASS (amp_package_node_parent_class)->copy (old_node);
197 // FIXME: We should probably copy the version number too because it will not
198 // be updated when the node is reloaded. So later when updating the old_node,
199 // the value will be overwritten with the new node empty value.
200 amp_package_node_add_token (AMP_PACKAGE_NODE (new_node), amp_package_node_get_token (AMP_PACKAGE_NODE (old_node)));
201
202 return new_node;
203 }
204
205 static gboolean
amp_package_node_write(AmpNode * node,AmpNode * parent,AmpProject * project,GError ** error)206 amp_package_node_write (AmpNode *node, AmpNode *parent, AmpProject *project, GError **error)
207 {
208 return amp_package_node_create_token (project, AMP_PACKAGE_NODE (node), error);
209 }
210
211 static gboolean
amp_package_node_erase(AmpNode * node,AmpNode * parent,AmpProject * project,GError ** error)212 amp_package_node_erase (AmpNode *node, AmpNode *parent, AmpProject *project, GError **error)
213 {
214 return amp_package_node_delete_token (project, AMP_PACKAGE_NODE (node), error);
215 }
216
217
218 /* GObjet implementation
219 *---------------------------------------------------------------------------*/
220
221 static void
amp_package_node_init(AmpPackageNode * node)222 amp_package_node_init (AmpPackageNode *node)
223 {
224 node->base.type = ANJUTA_PROJECT_PACKAGE;
225 node->base.properties_info = amp_get_package_property_list();
226 node->base.state = ANJUTA_PROJECT_CAN_REMOVE;
227 node->version = NULL;
228 }
229
230 static void
amp_package_node_finalize(GObject * object)231 amp_package_node_finalize (GObject *object)
232 {
233 AmpPackageNode *node = AMP_PACKAGE_NODE (object);
234
235 g_list_foreach (node->base.properties, (GFunc)amp_property_free, NULL);
236
237 G_OBJECT_CLASS (amp_package_node_parent_class)->finalize (object);
238 }
239
240 static void
amp_package_node_class_init(AmpPackageNodeClass * klass)241 amp_package_node_class_init (AmpPackageNodeClass *klass)
242 {
243 GObjectClass* object_class = G_OBJECT_CLASS (klass);
244 AmpNodeClass* node_class;
245
246 object_class->finalize = amp_package_node_finalize;
247
248 node_class = AMP_NODE_CLASS (klass);
249 node_class->load = amp_package_node_load;
250 node_class->update = amp_package_node_update;
251 node_class->copy = amp_package_node_copy;
252 node_class->erase = amp_package_node_erase;
253 node_class->write = amp_package_node_write;
254 }
255
256 static void
amp_package_node_class_finalize(AmpPackageNodeClass * klass)257 amp_package_node_class_finalize (AmpPackageNodeClass *klass)
258 {
259 }
260
261 void
amp_package_node_register(GTypeModule * module)262 amp_package_node_register (GTypeModule *module)
263 {
264 amp_package_node_register_type (module);
265 }
266