2 * utils.h - this file is part of Geany, a fast and lightweight IDE
4 * Copyright 2005 The Geany contributors
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 along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 * General utility functions, non-GTK related.
27 #define GEANY_UTILS_H 1
33 #include <gdk/gdk.h> /* for GdkColor */
37 /** Returns @c TRUE if @a ptr is @c NULL or @c *ptr is @c FALSE. */
41 /** @deprecated 2013/08 - use @c !EMPTY() instead. */
42 #ifndef GEANY_DISABLE_DEPRECATED
43 #define NZV(ptr) (!EMPTY(ptr))
46 /** Assigns @a result to @a ptr, then frees the old value.
47 * @a result can be an expression using the 'old' value of @a ptr.
48 * E.g. @code SETPTR(str, g_strndup(str, 5)); @endcode
50 #define SETPTR(ptr, result) \
52 gpointer setptr_tmp = ptr;\
57 #ifndef GEANY_DISABLE_DEPRECATED
58 /** @deprecated 2011/11/15 - use SETPTR() instead. */
59 #define setptr(ptr, result) \
61 gpointer setptr_tmp = ptr;\
67 /** Duplicates a string on the stack using @c g_alloca().
68 * Like glibc's @c strdupa(), but portable.
69 * @note You must include @c string.h yourself.
70 * @warning Don't use excessively or for long strings otherwise there may be stack exhaustion -
71 * see the GLib docs for @c g_alloca(). */
72 #define utils_strdupa(str) \
73 strcpy(g_alloca(strlen(str) + 1), str)
75 /* Get a keyfile setting, using the home keyfile if the key exists,
76 * otherwise system keyfile. */
77 #define utils_get_setting(type, home, sys, group, key, default_val)\
78 (g_key_file_has_key(home, group, key, NULL)) ?\
79 utils_get_setting_##type(home, group, key, default_val) :\
80 utils_get_setting_##type(sys, group, key, default_val)
82 /* ignore the case of filenames and paths under WIN32, causes errors if not */
84 #define utils_filenamecmp(a, b) utils_str_casecmp((a), (b))
86 #define utils_filenamecmp(a, b) strcmp((a), (b))
90 /** Iterates all the items in @a array using pointers.
91 * @param item pointer to an item in @a array.
92 * @param array C array to traverse.
93 * @param len Length of the array. */
94 #define foreach_c_array(item, array, len) \
95 for (item = array; item < &array[len]; item++)
97 /** Iterates all items in @a array.
98 * @param type Type of @a item.
99 * @param item pointer to item in @a array.
100 * @param array @c GArray to traverse. */
101 #define foreach_array(type, item, array) \
102 foreach_c_array(item, ((type*)(gpointer)array->data), array->len)
104 /** Iterates all the pointers in @a ptr_array.
105 * @param item pointer in @a ptr_array.
106 * @param idx @c guint index into @a ptr_array.
107 * @param ptr_array @c GPtrArray to traverse. */
108 #define foreach_ptr_array(item, idx, ptr_array) \
109 for (idx = 0; idx < (ptr_array)->len && (item = g_ptr_array_index((ptr_array), idx), TRUE); ++idx)
111 /** Iterates all the nodes in @a list.
112 * @param node should be a (@c GList*).
113 * @param list @c GList to traverse. */
114 #define foreach_list(node, list) \
115 for (node = list; node != NULL; node = node->next)
117 /** Iterates all the nodes in @a list.
118 * @param node should be a (@c GSList*).
119 * @param list @c GSList to traverse. */
120 #define foreach_slist(node, list) \
121 foreach_list(node, list)
123 /* Iterates all the nodes in @a list. Safe against removal during iteration
124 * @param node should be a (@c GList*).
125 * @param list @c GList to traverse. */
126 #define foreach_list_safe(node, list) \
127 for (GList *_node = (list), *_next = (list) ? (list)->next : NULL; \
128 (node = _node) != NULL; \
129 _node = _next, _next = _next ? _next->next : NULL)
131 /** Iterates through each unsorted filename in a @c GDir.
132 * @param filename (@c const @c gchar*) locale-encoded filename, without path. Do not modify or free.
133 * @param dir @c GDir created with @c g_dir_open(). Call @c g_dir_close() afterwards.
134 * @see utils_get_file_list() if you want a sorted list.
135 * @since Geany 0.19. */
136 #define foreach_dir(filename, dir)\
137 for ((filename) = g_dir_read_name(dir); (filename) != NULL; (filename) = g_dir_read_name(dir))
139 /** Iterates through each character in @a string.
140 * @param char_ptr Pointer to character.
141 * @param string String to traverse.
142 * @warning Doesn't include null terminating character.
143 * @since Geany 0.19. */
144 #define foreach_str(char_ptr, string) \
145 for (char_ptr = string; *char_ptr; char_ptr++)
147 /** Iterates a null-terminated string vector.
148 * @param str_ptr @c gchar** pointer to string element.
149 * @param strv Can be @c NULL.
150 * @since Geany 0.20 */
151 #define foreach_strv(str_ptr, strv)\
152 if (!(strv)) {} else foreach_str(str_ptr, strv)
154 /** Iterates from 0 to @a size.
156 * @param size Number of iterations.
157 * @since Geany 0.20. */
158 #define foreach_range(i, size) \
159 for (i = 0; i < size; i++)
162 gboolean
utils_str_equal(const gchar
*a
, const gchar
*b
);
164 guint
utils_string_replace_all(GString
*haystack
, const gchar
*needle
, const gchar
*replace
);
166 GSList
*utils_get_file_list(const gchar
*path
, guint
*length
, GError
**error
);
168 GSList
*utils_get_file_list_full(const gchar
*path
, gboolean full_path
, gboolean sort
, GError
**error
);
170 gint
utils_write_file(const gchar
*filename
, const gchar
*text
);
172 gchar
*utils_get_locale_from_utf8(const gchar
*utf8_text
);
174 gchar
*utils_get_utf8_from_locale(const gchar
*locale_text
);
176 gchar
*utils_remove_ext_from_filename(const gchar
*filename
);
178 gint
utils_mkdir(const gchar
*path
, gboolean create_parent_dirs
);
180 gboolean
utils_get_setting_boolean(GKeyFile
*config
, const gchar
*section
, const gchar
*key
, const gboolean default_value
);
182 gint
utils_get_setting_integer(GKeyFile
*config
, const gchar
*section
, const gchar
*key
, const gint default_value
);
184 gdouble
utils_get_setting_double(GKeyFile
*config
, const gchar
*section
, const gchar
*key
, const gdouble default_value
);
186 gchar
*utils_get_setting_string(GKeyFile
*config
, const gchar
*section
, const gchar
*key
, const gchar
*default_value
);
188 gboolean
utils_spawn_sync(const gchar
*dir
, gchar
**argv
, gchar
**env
, GSpawnFlags flags
,
189 GSpawnChildSetupFunc child_setup
, gpointer user_data
, gchar
**std_out
,
190 gchar
**std_err
, gint
*exit_status
, GError
**error
);
192 gboolean
utils_spawn_async(const gchar
*dir
, gchar
**argv
, gchar
**env
, GSpawnFlags flags
,
193 GSpawnChildSetupFunc child_setup
, gpointer user_data
, GPid
*child_pid
,
196 gint
utils_str_casecmp(const gchar
*s1
, const gchar
*s2
);
198 gchar
*utils_get_date_time(const gchar
*format
, time_t *time_to_use
);
200 void utils_open_browser(const gchar
*uri
);
202 guint
utils_string_replace_first(GString
*haystack
, const gchar
*needle
, const gchar
*replace
);
204 gchar
*utils_str_middle_truncate(const gchar
*string
, guint truncate_length
);
206 gchar
*utils_str_remove_chars(gchar
*string
, const gchar
*chars
);
208 gchar
**utils_copy_environment(const gchar
**exclude_vars
, const gchar
*first_varname
, ...) G_GNUC_NULL_TERMINATED
;
210 gchar
*utils_find_open_xml_tag(const gchar sel
[], gint size
);
212 const gchar
*utils_find_open_xml_tag_pos(const gchar sel
[], gint size
);
214 gchar
*utils_get_real_path(const gchar
*file_name
);
216 gchar
**utils_strv_shorten_file_list(gchar
**file_names
, gssize file_names_len
);
220 /* Casts a GDestroyNotify to a GClosureNotify without a warning.
221 * This is kinda shady, but likely works with platforms where GTK does. */
222 #define CLOSURE_NOTIFY(f) ((GClosureNotify) (void(*)(void)) (GDestroyNotify) (f))
231 RESOURCE_DIR_LIBEXEC
,
234 } GeanyResourceDirType
;
237 gint
utils_get_line_endings(const gchar
* buffer
, gsize size
);
239 gboolean
utils_isbrace(gchar c
, gboolean include_angles
);
241 gboolean
utils_is_opening_brace(gchar c
, gboolean include_angles
);
243 gboolean
utils_is_short_html_tag(const gchar
*tag_name
);
245 void utils_ensure_same_eol_characters(GString
*string
, gint target_eol_mode
);
247 const gchar
*utils_get_eol_char(gint eol_mode
);
249 const gchar
*utils_get_eol_name(gint eol_mode
);
251 const gchar
*utils_get_eol_short_name(gint eol_mode
);
253 gboolean
utils_atob(const gchar
*str
);
255 void utils_tidy_path(gchar
*filename
);
257 gboolean
utils_is_absolute_path(const gchar
*path
);
259 const gchar
*utils_path_skip_root(const gchar
*path
);
261 gdouble
utils_scale_round(gdouble val
, gdouble factor
);
263 gchar
utils_brace_opposite(gchar ch
);
265 gint
utils_string_find(GString
*haystack
, gint start
, gint end
, const gchar
*needle
);
267 gint
utils_string_replace(GString
*str
, gint pos
, gint len
, const gchar
*replace
);
269 guint
utils_string_regex_replace_all(GString
*haystack
, GRegex
*regex
,
270 guint match_num
, const gchar
*replace
, gboolean literal
);
272 void utils_str_replace_all(gchar
**haystack
, const gchar
*needle
, const gchar
*replacement
);
274 gint
utils_strpos(const gchar
* haystack
, const gchar
*needle
);
276 gchar
*utils_get_initials(const gchar
*name
);
278 gchar
*utils_get_hex_from_color(GdkColor
*color
);
280 const gchar
*utils_get_default_dir_utf8(void);
282 gchar
*utils_get_current_file_dir_utf8(void);
284 void utils_beep(void);
286 gboolean
utils_parse_color(const gchar
*spec
, GdkColor
*color
);
288 gint
utils_color_to_bgr(const GdkColor
*color
);
290 gint
utils_parse_color_to_bgr(const gchar
*spec
);
292 gchar
*utils_get_current_time_string(gboolean include_microseconds
);
294 GIOChannel
*utils_set_up_io_channel(gint fd
, GIOCondition cond
, gboolean nblock
,
295 GIOFunc func
, gpointer data
);
297 gboolean
utils_str_replace_escape(gchar
*string
, gboolean keep_backslash
);
299 gboolean
utils_wrap_string(gchar
*string
, gint wrapstart
);
301 void utils_free_pointers(gsize arg_count
, ...) G_GNUC_NULL_TERMINATED
;
303 gchar
**utils_strv_new(const gchar
*first
, ...) G_GNUC_NULL_TERMINATED
;
305 gchar
**utils_strv_join(gchar
**first
, gchar
**second
) G_GNUC_WARN_UNUSED_RESULT
;
307 gchar
*utils_strv_find_common_prefix(gchar
**strv
, gssize strv_len
) G_GNUC_WARN_UNUSED_RESULT
;
309 gchar
*utils_strv_find_lcs(gchar
**strv
, gssize strv_len
, const gchar
*delim
) G_GNUC_WARN_UNUSED_RESULT
;
311 GSList
*utils_get_config_files(const gchar
*subdir
);
313 gchar
*utils_get_help_url(const gchar
*suffix
);
315 gboolean
utils_str_has_upper(const gchar
*str
);
317 gint
utils_is_file_writable(const gchar
*locale_filename
);
319 const gchar
*utils_get_uri_file_prefix(void);
321 gchar
*utils_get_path_from_uri(const gchar
*uri
);
323 gboolean
utils_is_uri(const gchar
*uri
);
325 gboolean
utils_is_remote_path(const gchar
*path
);
327 GDate
*utils_parse_date(const gchar
*input
);
329 gchar
*utils_parse_and_format_build_date(const gchar
*input
);
331 gchar
*utils_get_user_config_dir(void);
333 const gchar
*utils_resource_dir(GeanyResourceDirType type
);
335 void utils_start_new_geany_instance(const gchar
*doc_path
);
337 gchar
*utils_get_os_info_string(void);
339 gchar
*utils_utf8_strdown(const gchar
*str
);
341 #endif /* GEANY_PRIVATE */
345 #endif /* GEANY_UTILS_H */