1 /* 2 * utils.h - this file is part of Geany, a fast and lightweight IDE 3 * 4 * Copyright 2005 The Geany contributors 5 * 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. 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 14 * 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, write to the Free Software Foundation, Inc., 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 */ 20 21 /** 22 * @file: utils.h 23 * General utility functions, non-GTK related. 24 */ 25 26 #ifndef GEANY_UTILS_H 27 #define GEANY_UTILS_H 1 28 29 #include <string.h> 30 #include <time.h> 31 32 #include <glib.h> 33 #include <gdk/gdk.h> /* for GdkColor */ 34 35 G_BEGIN_DECLS 36 37 /** Returns @c TRUE if @a ptr is @c NULL or @c *ptr is @c FALSE. */ 38 #define EMPTY(ptr) \ 39 (!(ptr) || !*(ptr)) 40 41 /** @deprecated 2013/08 - use @c !EMPTY() instead. */ 42 #ifndef GEANY_DISABLE_DEPRECATED 43 #define NZV(ptr) (!EMPTY(ptr)) 44 #endif 45 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 49 **/ 50 #define SETPTR(ptr, result) \ 51 do {\ 52 gpointer setptr_tmp = ptr;\ 53 ptr = result;\ 54 g_free(setptr_tmp);\ 55 } while (0) 56 57 #ifndef GEANY_DISABLE_DEPRECATED 58 /** @deprecated 2011/11/15 - use SETPTR() instead. */ 59 #define setptr(ptr, result) \ 60 {\ 61 gpointer setptr_tmp = ptr;\ 62 ptr = result;\ 63 g_free(setptr_tmp);\ 64 } 65 #endif 66 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) 74 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) 81 82 /* ignore the case of filenames and paths under WIN32, causes errors if not */ 83 #ifdef G_OS_WIN32 84 #define utils_filenamecmp(a, b) utils_str_casecmp((a), (b)) 85 #else 86 #define utils_filenamecmp(a, b) strcmp((a), (b)) 87 #endif 88 89 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++) 96 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) 103 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, item = ((ptr_array)->len > 0 ? g_ptr_array_index((ptr_array), 0) : NULL); \ 110 idx < (ptr_array)->len; ++idx, item = g_ptr_array_index((ptr_array), idx)) 111 112 /** Iterates all the nodes in @a list. 113 * @param node should be a (@c GList*). 114 * @param list @c GList to traverse. */ 115 #define foreach_list(node, list) \ 116 for (node = list; node != NULL; node = node->next) 117 118 /** Iterates all the nodes in @a list. 119 * @param node should be a (@c GSList*). 120 * @param list @c GSList to traverse. */ 121 #define foreach_slist(node, list) \ 122 foreach_list(node, list) 123 124 /* Iterates all the nodes in @a list. Safe against removal during iteration 125 * @param node should be a (@c GList*). 126 * @param list @c GList to traverse. */ 127 #define foreach_list_safe(node, list) \ 128 for (GList *_node = (list), *_next = (list) ? (list)->next : NULL; \ 129 (node = _node) != NULL; \ 130 _node = _next, _next = _next ? _next->next : NULL) 131 132 /** Iterates through each unsorted filename in a @c GDir. 133 * @param filename (@c const @c gchar*) locale-encoded filename, without path. Do not modify or free. 134 * @param dir @c GDir created with @c g_dir_open(). Call @c g_dir_close() afterwards. 135 * @see utils_get_file_list() if you want a sorted list. 136 * @since Geany 0.19. */ 137 #define foreach_dir(filename, dir)\ 138 for ((filename) = g_dir_read_name(dir); (filename) != NULL; (filename) = g_dir_read_name(dir)) 139 140 /** Iterates through each character in @a string. 141 * @param char_ptr Pointer to character. 142 * @param string String to traverse. 143 * @warning Doesn't include null terminating character. 144 * @since Geany 0.19. */ 145 #define foreach_str(char_ptr, string) \ 146 for (char_ptr = string; *char_ptr; char_ptr++) 147 148 /** Iterates a null-terminated string vector. 149 * @param str_ptr @c gchar** pointer to string element. 150 * @param strv Can be @c NULL. 151 * @since Geany 0.20 */ 152 #define foreach_strv(str_ptr, strv)\ 153 if (!(strv)) {} else foreach_str(str_ptr, strv) 154 155 /** Iterates from 0 to @a size. 156 * @param i Integer. 157 * @param size Number of iterations. 158 * @since Geany 0.20. */ 159 #define foreach_range(i, size) \ 160 for (i = 0; i < size; i++) 161 162 163 gboolean utils_str_equal(const gchar *a, const gchar *b); 164 165 guint utils_string_replace_all(GString *haystack, const gchar *needle, const gchar *replace); 166 167 GSList *utils_get_file_list(const gchar *path, guint *length, GError **error); 168 169 GSList *utils_get_file_list_full(const gchar *path, gboolean full_path, gboolean sort, GError **error); 170 171 gint utils_write_file(const gchar *filename, const gchar *text); 172 173 gchar *utils_get_locale_from_utf8(const gchar *utf8_text); 174 175 gchar *utils_get_utf8_from_locale(const gchar *locale_text); 176 177 gchar *utils_remove_ext_from_filename(const gchar *filename); 178 179 gint utils_mkdir(const gchar *path, gboolean create_parent_dirs); 180 181 gboolean utils_get_setting_boolean(GKeyFile *config, const gchar *section, const gchar *key, const gboolean default_value); 182 183 gint utils_get_setting_integer(GKeyFile *config, const gchar *section, const gchar *key, const gint default_value); 184 185 gchar *utils_get_setting_string(GKeyFile *config, const gchar *section, const gchar *key, const gchar *default_value); 186 187 gboolean utils_spawn_sync(const gchar *dir, gchar **argv, gchar **env, GSpawnFlags flags, 188 GSpawnChildSetupFunc child_setup, gpointer user_data, gchar **std_out, 189 gchar **std_err, gint *exit_status, GError **error); 190 191 gboolean utils_spawn_async(const gchar *dir, gchar **argv, gchar **env, GSpawnFlags flags, 192 GSpawnChildSetupFunc child_setup, gpointer user_data, GPid *child_pid, 193 GError **error); 194 195 gint utils_str_casecmp(const gchar *s1, const gchar *s2); 196 197 gchar *utils_get_date_time(const gchar *format, time_t *time_to_use); 198 199 void utils_open_browser(const gchar *uri); 200 201 guint utils_string_replace_first(GString *haystack, const gchar *needle, const gchar *replace); 202 203 gchar *utils_str_middle_truncate(const gchar *string, guint truncate_length); 204 205 gchar *utils_str_remove_chars(gchar *string, const gchar *chars); 206 207 gchar **utils_copy_environment(const gchar **exclude_vars, const gchar *first_varname, ...) G_GNUC_NULL_TERMINATED; 208 209 gchar *utils_find_open_xml_tag(const gchar sel[], gint size); 210 211 const gchar *utils_find_open_xml_tag_pos(const gchar sel[], gint size); 212 213 gchar *utils_get_real_path(const gchar *file_name); 214 215 gchar **utils_strv_shorten_file_list(gchar **file_names, gssize file_names_len); 216 217 #ifdef GEANY_PRIVATE 218 219 typedef enum 220 { 221 RESOURCE_DIR_DATA, 222 RESOURCE_DIR_ICON, 223 RESOURCE_DIR_DOC, 224 RESOURCE_DIR_LOCALE, 225 RESOURCE_DIR_PLUGIN, 226 RESOURCE_DIR_LIBEXEC, 227 228 RESOURCE_DIR_COUNT 229 } GeanyResourceDirType; 230 231 232 gint utils_get_line_endings(const gchar* buffer, gsize size); 233 234 gboolean utils_isbrace(gchar c, gboolean include_angles); 235 236 gboolean utils_is_opening_brace(gchar c, gboolean include_angles); 237 238 gboolean utils_is_short_html_tag(const gchar *tag_name); 239 240 void utils_ensure_same_eol_characters(GString *string, gint target_eol_mode); 241 242 const gchar *utils_get_eol_char(gint eol_mode); 243 244 const gchar *utils_get_eol_name(gint eol_mode); 245 246 const gchar *utils_get_eol_short_name(gint eol_mode); 247 248 gboolean utils_atob(const gchar *str); 249 250 void utils_tidy_path(gchar *filename); 251 252 gboolean utils_is_absolute_path(const gchar *path); 253 254 const gchar *utils_path_skip_root(const gchar *path); 255 256 gdouble utils_scale_round(gdouble val, gdouble factor); 257 258 gchar utils_brace_opposite(gchar ch); 259 260 gint utils_string_find(GString *haystack, gint start, gint end, const gchar *needle); 261 262 gint utils_string_replace(GString *str, gint pos, gint len, const gchar *replace); 263 264 guint utils_string_regex_replace_all(GString *haystack, GRegex *regex, 265 guint match_num, const gchar *replace, gboolean literal); 266 267 void utils_str_replace_all(gchar **haystack, const gchar *needle, const gchar *replacement); 268 269 gint utils_strpos(const gchar* haystack, const gchar *needle); 270 271 gchar *utils_get_initials(const gchar *name); 272 273 gchar *utils_get_hex_from_color(GdkColor *color); 274 275 const gchar *utils_get_default_dir_utf8(void); 276 277 gchar *utils_get_current_file_dir_utf8(void); 278 279 void utils_beep(void); 280 281 gchar *utils_make_human_readable_str(guint64 size, gulong block_size, 282 gulong display_unit); 283 284 gboolean utils_parse_color(const gchar *spec, GdkColor *color); 285 286 gint utils_color_to_bgr(const GdkColor *color); 287 288 gint utils_parse_color_to_bgr(const gchar *spec); 289 290 gchar *utils_get_current_time_string(gboolean include_microseconds); 291 292 GIOChannel *utils_set_up_io_channel(gint fd, GIOCondition cond, gboolean nblock, 293 GIOFunc func, gpointer data); 294 295 gboolean utils_str_replace_escape(gchar *string, gboolean keep_backslash); 296 297 gboolean utils_wrap_string(gchar *string, gint wrapstart); 298 299 void utils_free_pointers(gsize arg_count, ...) G_GNUC_NULL_TERMINATED; 300 301 gchar **utils_strv_new(const gchar *first, ...) G_GNUC_NULL_TERMINATED; 302 303 gchar **utils_strv_join(gchar **first, gchar **second) G_GNUC_WARN_UNUSED_RESULT; 304 305 gchar *utils_strv_find_common_prefix(gchar **strv, gssize strv_len) G_GNUC_WARN_UNUSED_RESULT; 306 307 gchar *utils_strv_find_lcs(gchar **strv, gssize strv_len, const gchar *delim) G_GNUC_WARN_UNUSED_RESULT; 308 309 GSList *utils_get_config_files(const gchar *subdir); 310 311 gchar *utils_get_help_url(const gchar *suffix); 312 313 gboolean utils_str_has_upper(const gchar *str); 314 315 gint utils_is_file_writable(const gchar *locale_filename); 316 317 const gchar *utils_get_uri_file_prefix(void); 318 319 gchar *utils_get_path_from_uri(const gchar *uri); 320 321 gboolean utils_is_uri(const gchar *uri); 322 323 gboolean utils_is_remote_path(const gchar *path); 324 325 GDate *utils_parse_date(const gchar *input); 326 327 gchar *utils_parse_and_format_build_date(const gchar *input); 328 329 gchar *utils_get_user_config_dir(void); 330 331 const gchar *utils_resource_dir(GeanyResourceDirType type); 332 333 void utils_start_new_geany_instance(const gchar *doc_path); 334 335 gchar *utils_get_os_info_string(void); 336 337 #endif /* GEANY_PRIVATE */ 338 339 G_END_DECLS 340 341 #endif /* GEANY_UTILS_H */ 342