1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3  * anjuta
4  * Copyright (C) Johannes Schmid 2011 <jhs@Obelix>
5  *
6  * anjuta is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * anjuta is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 /**
21  * SECTION: anjuta-pkg-scanner
22  * @short_description: Scan files contained by a library using pkg-config
23  * @see_also: #AnjutaAsyncCommand
24  * @include libanjuta/anjuta-pkg-scanner.h
25  *
26  * #AnjutaPkgScanner is an async command that can be used to query the list
27  * of files and the version of a package.
28  *
29  */
30 
31 #include <libanjuta/anjuta-pkg-scanner.h>
32 #include <libanjuta/anjuta-utils.h>
33 #include <libanjuta/anjuta-pkg-config.h>
34 #include <gio/gio.h>
35 
36 enum
37 {
38 	PROP_0,
39 	PROP_PACKAGE,
40 	PROP_VERSION
41 };
42 
43 struct _AnjutaPkgScannerPrivate
44 {
45 	gchar* package;
46 	gchar* version;
47 	GList* files;
48 };
49 
50 G_DEFINE_TYPE (AnjutaPkgScanner, anjuta_pkg_scanner, ANJUTA_TYPE_ASYNC_COMMAND);
51 
52 
53 
54 static void
anjuta_pkg_scanner_init(AnjutaPkgScanner * object)55 anjuta_pkg_scanner_init (AnjutaPkgScanner *object)
56 {
57 	object->priv = G_TYPE_INSTANCE_GET_PRIVATE (object,
58 	                                            ANJUTA_TYPE_PKG_SCANNER,
59 	                                            AnjutaPkgScannerPrivate);
60 	object->priv->files = NULL;
61 }
62 
63 static void
anjuta_pkg_scanner_finalize(GObject * object)64 anjuta_pkg_scanner_finalize (GObject *object)
65 {
66 	AnjutaPkgScanner* scanner = ANJUTA_PKG_SCANNER (object);
67 	g_free (scanner->priv->package);
68 	g_free (scanner->priv->version);
69 	anjuta_util_glist_strings_free (scanner->priv->files);
70 
71 	G_OBJECT_CLASS (anjuta_pkg_scanner_parent_class)->finalize (object);
72 }
73 
74 static void
anjuta_pkg_scanner_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)75 anjuta_pkg_scanner_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
76 {
77 	AnjutaPkgScanner* scanner;
78 
79 	g_return_if_fail (ANJUTA_IS_PKG_SCANNER (object));
80 
81 	scanner = ANJUTA_PKG_SCANNER(object);
82 
83 	switch (prop_id)
84 	{
85 	case PROP_PACKAGE:
86 		scanner->priv->package = g_value_dup_string (value);
87 		break;
88 	case PROP_VERSION:
89 		scanner->priv->version = g_value_dup_string (value);
90 		break;
91 	default:
92 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
93 		break;
94 	}
95 }
96 
97 static void
anjuta_pkg_scanner_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)98 anjuta_pkg_scanner_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
99 {
100 	AnjutaPkgScanner* scanner;
101 
102 	g_return_if_fail (ANJUTA_IS_PKG_SCANNER (object));
103 
104 	scanner = ANJUTA_PKG_SCANNER(object);
105 
106 	switch (prop_id)
107 	{
108 		case PROP_PACKAGE:
109 			g_value_set_string (value, scanner->priv->package);
110 			break;
111 		case PROP_VERSION:
112 			g_value_set_string (value, scanner->priv->version);
113 			break;
114 	default:
115 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
116 		break;
117 	}
118 }
119 
120 static void
anjuta_pkg_scanner_list_files(GList ** children,GFile * dir)121 anjuta_pkg_scanner_list_files (GList **children, GFile *dir)
122 {
123 	GFileEnumerator *list;
124 
125 	list = g_file_enumerate_children (dir,
126 	    G_FILE_ATTRIBUTE_STANDARD_NAME,
127 	    G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
128 	    NULL,
129 	    NULL);
130 
131 	if (list != NULL)
132 	{
133 		GFileInfo *info;
134 
135 		while ((info = g_file_enumerator_next_file (list, NULL, NULL)) != NULL)
136 		{
137 			const gchar *name;
138 			GFile *file;
139 
140 			name = g_file_info_get_name (info);
141 			file = g_file_get_child (dir, name);
142 			g_object_unref (info);
143 
144 			if (g_file_query_file_type (file, G_FILE_QUERY_INFO_NONE, NULL) == G_FILE_TYPE_DIRECTORY)
145 			{
146 				anjuta_pkg_scanner_list_files (children, file);
147 			}
148 			else
149 			{
150 				gchar* filename = g_file_get_path (file);
151 				*children = g_list_prepend (*children, filename);
152 			}
153 			g_object_unref (file);
154 		}
155 		g_file_enumerator_close (list, NULL, NULL);
156 		g_object_unref (list);
157 	}
158 }
159 
160 static guint
anjuta_pkg_scanner_run(AnjutaCommand * command)161 anjuta_pkg_scanner_run (AnjutaCommand* command)
162 {
163 	AnjutaPkgScanner* scanner = ANJUTA_PKG_SCANNER (command);
164 	GList* dirs = anjuta_pkg_config_get_directories (scanner->priv->package, TRUE, NULL);
165 	GList* dir;
166 
167 	for (dir = dirs; dir != NULL; dir = g_list_next (dir))
168 	{
169 		GFile* file = g_file_new_for_path (dir->data);
170 		anjuta_pkg_scanner_list_files (&scanner->priv->files, file);
171 	}
172 	anjuta_util_glist_strings_free (dirs);
173 	return 0;
174 }
175 
176 static void
anjuta_pkg_scanner_class_init(AnjutaPkgScannerClass * klass)177 anjuta_pkg_scanner_class_init (AnjutaPkgScannerClass *klass)
178 {
179 	GObjectClass* object_class = G_OBJECT_CLASS (klass);
180 	AnjutaCommandClass* command_class = ANJUTA_COMMAND_CLASS (klass);
181 
182 	object_class->finalize = anjuta_pkg_scanner_finalize;
183 	object_class->set_property = anjuta_pkg_scanner_set_property;
184 	object_class->get_property = anjuta_pkg_scanner_get_property;
185 
186 	g_object_class_install_property (object_class,
187 	                                 PROP_PACKAGE,
188 	                                 g_param_spec_string ("package",
189 	                                                      "package",
190 	                                                      "Name of the package",
191 	                                                      NULL,
192 	                                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
193 
194 	g_object_class_install_property (object_class,
195 	                                 PROP_VERSION,
196 	                                 g_param_spec_string ("version",
197 	                                                      "version",
198 	                                                      "Version of the package",
199 	                                                      NULL,
200 	                                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
201 
202 	command_class->run = anjuta_pkg_scanner_run;
203 
204 	g_type_class_add_private (klass, sizeof (AnjutaPkgScannerPrivate));
205 }
206 
207 /*
208  * anjuta_pkg_scanner_new:
209  * @package: Name of the package to scan
210  * @version: Version of the package
211  *
212  * Returns: a new #AnjutaCommand to scan for files.
213  */
214 AnjutaCommand*
anjuta_pkg_scanner_new(const gchar * package,const gchar * version)215 anjuta_pkg_scanner_new (const gchar* package, const gchar* version)
216 {
217 	GObject* object =
218 		g_object_new (ANJUTA_TYPE_PKG_SCANNER,
219 		              "package", package,
220 		              "version", version,
221 		              NULL);
222 
223 	return ANJUTA_COMMAND (object);
224 }
225 
226 /*
227  * anjuta_pkg_scanner_get_files:
228  * @scanner: PkgScanner object
229  *
230  * Returns: Name of the package to scan.
231  */
232 const gchar*
anjuta_pkg_scanner_get_package(AnjutaPkgScanner * scanner)233 anjuta_pkg_scanner_get_package (AnjutaPkgScanner* scanner)
234 {
235 	return scanner->priv->package;
236 }
237 
238 /*
239  * anjuta_pkg_scanner_get_files:
240  * @scanner: PkgScanner object
241  *
242  * Returns: Version of the package to scan.
243  */
244 const gchar*
anjuta_pkg_scanner_get_version(AnjutaPkgScanner * scanner)245 anjuta_pkg_scanner_get_version (AnjutaPkgScanner* scanner)
246 {
247 	return scanner->priv->version;
248 }
249 
250 /*
251  * anjuta_pkg_scanner_get_files:
252  * @scanner: PkgScanner object
253  *
254  * Returns: (element-type GFile*): List of files to scan.
255  */
256 GList*
anjuta_pkg_scanner_get_files(AnjutaPkgScanner * scanner)257 anjuta_pkg_scanner_get_files (AnjutaPkgScanner* scanner)
258 {
259 	return scanner->priv->files;
260 }
261