1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) Johannes Schmid 2012 <jhs@gnome.org>
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.
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.
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/>.
20 #include "search-file-command.h"
23 struct _SearchFileCommandPrivate
29 gboolean case_sensitive
;
44 #define BUFFER_SIZE 1024
46 G_DEFINE_TYPE (SearchFileCommand
, search_file_command
, ANJUTA_TYPE_ASYNC_COMMAND
);
49 search_file_command_save (SearchFileCommand
* cmd
, const gchar
* new_content
, GError
**error
)
51 GFileOutputStream
* ostream
;
53 ostream
= g_file_replace (cmd
->priv
->file
,
63 /* TODO: Convert to original encoding */
64 g_output_stream_write_all (G_OUTPUT_STREAM(ostream
),
70 g_object_unref (ostream
);
74 search_file_command_load (SearchFileCommand
* cmd
, GError
**error
)
77 GFileInputStream
* istream
;
78 gchar buffer
[BUFFER_SIZE
];
81 istream
= g_file_read (cmd
->priv
->file
, NULL
, error
);
87 /* Read file into buffer */
88 content
= g_string_new (NULL
);
89 while ((bytes_read
= g_input_stream_read (G_INPUT_STREAM (istream
),
97 g_string_free (content
, TRUE
);
98 g_object_unref (istream
);
101 /* TODO: Non-UTF8 files... */
102 g_string_append_len (content
, buffer
, bytes_read
);
104 g_object_unref (istream
);
106 return g_string_free (content
, FALSE
);
110 search_file_command_run (AnjutaCommand
* anjuta_cmd
)
112 SearchFileCommand
* cmd
= SEARCH_FILE_COMMAND(anjuta_cmd
);
113 GError
* error
= NULL
;
117 GRegexCompileFlags flags
= G_REGEX_MULTILINE
;
119 GMatchInfo
*match_info
;
121 g_return_val_if_fail (cmd
->priv
->file
!= NULL
&& G_IS_FILE (cmd
->priv
->file
), 1);
122 g_return_val_if_fail (cmd
->priv
->pattern
!= NULL
, 1);
123 cmd
->priv
->n_matches
= 0;
125 content
= search_file_command_load (cmd
, &error
);
128 int code
= error
->code
;
129 g_error_free (error
);
133 if (!cmd
->priv
->regex
)
135 pattern
= g_regex_escape_string (cmd
->priv
->pattern
, -1);
136 if (cmd
->priv
->replace
)
137 replace
= g_regex_escape_string (cmd
->priv
->replace
, -1);
143 pattern
= g_strdup (cmd
->priv
->pattern
);
144 if (cmd
->priv
->replace
)
145 replace
= g_strdup (cmd
->priv
->replace
);
150 if (!cmd
->priv
->case_sensitive
)
151 flags
|= G_REGEX_CASELESS
;
153 regex
= g_regex_new (pattern
, flags
, 0, &error
);
156 anjuta_command_set_error_message(anjuta_cmd
, error
->message
);
157 g_error_free (error
);
161 g_regex_match (regex
, content
, 0, &match_info
);
162 while (g_match_info_matches (match_info
))
164 cmd
->priv
->n_matches
++;
165 g_match_info_next (match_info
, NULL
);
167 g_match_info_free (match_info
);
169 if (replace
&& cmd
->priv
->n_matches
)
173 new_content
= g_regex_replace (regex
, content
, -1, 0, replace
, 0, NULL
);
175 search_file_command_save (cmd
, new_content
, &error
);
176 g_free (new_content
);
180 anjuta_async_command_set_error_message (anjuta_cmd
, error
->message
);
185 g_regex_unref (regex
);
194 search_file_command_init (SearchFileCommand
*cmd
)
196 cmd
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (cmd
, SEARCH_TYPE_FILE_COMMAND
, SearchFileCommandPrivate
);
200 search_file_command_finalize (GObject
*object
)
202 SearchFileCommand
* cmd
= SEARCH_FILE_COMMAND (object
);
205 g_object_unref (cmd
->priv
->file
);
206 g_free (cmd
->priv
->pattern
);
207 g_free (cmd
->priv
->replace
);
209 G_OBJECT_CLASS (search_file_command_parent_class
)->finalize (object
);
213 search_file_command_set_property (GObject
*object
, guint prop_id
, const GValue
*value
, GParamSpec
*pspec
)
215 SearchFileCommand
* cmd
;
217 g_return_if_fail (SEARCH_IS_FILE_COMMAND (object
));
219 cmd
= SEARCH_FILE_COMMAND (object
);
225 g_object_unref (cmd
->priv
->file
);
226 cmd
->priv
->file
= g_value_dup_object (value
);
229 g_free (cmd
->priv
->pattern
);
230 cmd
->priv
->pattern
= g_value_dup_string (value
);
233 g_free (cmd
->priv
->replace
);
234 cmd
->priv
->replace
= g_value_dup_string (value
);
236 case PROP_CASE_SENSITIVE
:
237 cmd
->priv
->case_sensitive
= g_value_get_boolean (value
);
240 cmd
->priv
->regex
= g_value_get_boolean (value
);
243 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
249 search_file_command_get_property (GObject
*object
, guint prop_id
, GValue
*value
, GParamSpec
*pspec
)
251 SearchFileCommand
* cmd
;
253 g_return_if_fail (SEARCH_IS_FILE_COMMAND (object
));
255 cmd
= SEARCH_FILE_COMMAND (object
);
260 g_value_set_object (value
, cmd
->priv
->file
);
263 g_value_set_string (value
, cmd
->priv
->pattern
);
266 g_value_set_string (value
, cmd
->priv
->replace
);
268 case PROP_CASE_SENSITIVE
:
269 g_value_set_boolean (value
, cmd
->priv
->case_sensitive
);
272 g_value_set_boolean (value
, cmd
->priv
->regex
);
275 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
281 search_file_command_class_init (SearchFileCommandClass
*klass
)
283 GObjectClass
* object_class
= G_OBJECT_CLASS (klass
);
284 AnjutaCommandClass
* command_class
= ANJUTA_COMMAND_CLASS(klass
);
286 object_class
->finalize
= search_file_command_finalize
;
287 object_class
->set_property
= search_file_command_set_property
;
288 object_class
->get_property
= search_file_command_get_property
;
290 g_object_class_install_property (object_class
,
292 g_param_spec_object ("file",
294 "Filename to search in",
296 G_PARAM_WRITABLE
| G_PARAM_READABLE
| G_PARAM_CONSTRUCT_ONLY
));
298 g_object_class_install_property (object_class
,
300 g_param_spec_string ("pattern", "", "",
302 G_PARAM_WRITABLE
| G_PARAM_READABLE
| G_PARAM_CONSTRUCT_ONLY
));
303 g_object_class_install_property (object_class
,
305 g_param_spec_string ("replace", "", "",
307 G_PARAM_WRITABLE
| G_PARAM_READABLE
| G_PARAM_CONSTRUCT_ONLY
));
309 g_object_class_install_property (object_class
,
311 g_param_spec_boolean ("case-sensitive", "", "",
313 G_PARAM_WRITABLE
| G_PARAM_READABLE
| G_PARAM_CONSTRUCT_ONLY
));
315 g_object_class_install_property (object_class
,
317 g_param_spec_boolean ("regex", "", "",
319 G_PARAM_WRITABLE
| G_PARAM_READABLE
| G_PARAM_CONSTRUCT_ONLY
));
321 command_class
->run
= search_file_command_run
;
323 g_type_class_add_private (klass
, sizeof(SearchFileCommandPrivate
));
328 search_file_command_new (GFile
* file
, const gchar
* pattern
,
329 const gchar
* replace
, gboolean case_sensitive
, gboolean regex
)
331 SearchFileCommand
* command
;
333 command
= SEARCH_FILE_COMMAND (g_object_new (SEARCH_TYPE_FILE_COMMAND
,
337 "case-sensitive", case_sensitive
,
338 "regex", regex
, NULL
));
343 search_file_command_get_n_matches (SearchFileCommand
* cmd
)
345 g_return_val_if_fail (cmd
!= NULL
&& SEARCH_IS_FILE_COMMAND (cmd
), 0);
347 return cmd
->priv
->n_matches
;