glibcompat.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /*
  2. GLIB - Library of useful routines for C programming
  3. Copyright (C) 2009-2024
  4. Free Software Foundation, Inc.
  5. Written by:
  6. Slava Zanko <slavazanko@gmail.com>, 2009, 2013.
  7. This file is part of the Midnight Commander.
  8. The Midnight Commander is free software: you can redistribute it
  9. and/or modify it under the terms of the GNU General Public License as
  10. published by the Free Software Foundation, either version 3 of the License,
  11. or (at your option) any later version.
  12. The Midnight Commander is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. /** \file glibcompat.c
  20. * \brief Source: compatibility with older versions of glib
  21. *
  22. * Following code was copied from glib to GNU Midnight Commander to
  23. * provide compatibility with older versions of glib.
  24. */
  25. #include <config.h>
  26. #include <string.h>
  27. #include "global.h"
  28. #include "glibcompat.h"
  29. /*** global variables ****************************************************************************/
  30. /*** file scope macro definitions ****************************************************************/
  31. /*** file scope type declarations ****************************************************************/
  32. /*** file scope variables ************************************************************************/
  33. /* --------------------------------------------------------------------------------------------- */
  34. /*** file scope functions ************************************************************************/
  35. /* --------------------------------------------------------------------------------------------- */
  36. #if ! GLIB_CHECK_VERSION (2, 54, 0)
  37. /**
  38. * g_direct_equal:
  39. * @v1: (nullable): a key
  40. * @v2: (nullable): a key to compare with @v1
  41. *
  42. * Compares two #gpointer arguments and returns %TRUE if they are equal.
  43. * It can be passed to g_hash_table_new() as the @key_equal_func
  44. * parameter, when using opaque pointers compared by pointer value as
  45. * keys in a #GHashTable.
  46. *
  47. * This equality function is also appropriate for keys that are integers
  48. * stored in pointers, such as `GINT_TO_POINTER (n)`.
  49. *
  50. * Returns: %TRUE if the two keys match.
  51. */
  52. static gboolean
  53. g_direct_equal (gconstpointer v1, gconstpointer v2)
  54. {
  55. return v1 == v2;
  56. }
  57. #endif /* ! GLIB_CHECK_VERSION (2, 54, 0) */
  58. /* --------------------------------------------------------------------------------------------- */
  59. /*** public functions ****************************************************************************/
  60. /* --------------------------------------------------------------------------------------------- */
  61. #if ! GLIB_CHECK_VERSION (2, 54, 0)
  62. /**
  63. * g_ptr_array_find_with_equal_func: (skip)
  64. * @haystack: pointer array to be searched
  65. * @needle: pointer to look for
  66. * @equal_func: (nullable): the function to call for each element, which should
  67. * return %TRUE when the desired element is found; or %NULL to use pointer
  68. * equality
  69. * @index_: (optional) (out): return location for the index of
  70. * the element, if found
  71. *
  72. * Checks whether @needle exists in @haystack, using the given @equal_func.
  73. * If the element is found, %TRUE is returned and the element^A^A^As index is
  74. * returned in @index_ (if non-%NULL). Otherwise, %FALSE is returned and @index_
  75. * is undefined. If @needle exists multiple times in @haystack, the index of
  76. * the first instance is returned.
  77. *
  78. * @equal_func is called with the element from the array as its first parameter,
  79. * and @needle as its second parameter. If @equal_func is %NULL, pointer
  80. * equality is used.
  81. *
  82. * Returns: %TRUE if @needle is one of the elements of @haystack
  83. * Since: 2.54
  84. */
  85. gboolean
  86. g_ptr_array_find_with_equal_func (GPtrArray * haystack, gconstpointer needle, GEqualFunc equal_func,
  87. guint * index_)
  88. {
  89. guint i;
  90. g_return_val_if_fail (haystack != NULL, FALSE);
  91. if (equal_func == NULL)
  92. equal_func = g_direct_equal;
  93. for (i = 0; i < haystack->len; i++)
  94. if (equal_func (g_ptr_array_index (haystack, i), needle))
  95. {
  96. if (index_ != NULL)
  97. *index_ = i;
  98. return TRUE;
  99. }
  100. return FALSE;
  101. }
  102. #endif /* ! GLIB_CHECK_VERSION (2, 54, 0) */
  103. /* --------------------------------------------------------------------------------------------- */
  104. #if ! GLIB_CHECK_VERSION (2, 63, 3)
  105. /**
  106. * g_clear_slist: (skip)
  107. * @slist_ptr: (not nullable): a #GSList return location
  108. * @destroy: (nullable): the function to pass to g_slist_free_full() or NULL to not free elements
  109. *
  110. * Clears a pointer to a #GSList, freeing it and, optionally, freeing its elements using @destroy.
  111. *
  112. * @slist_ptr must be a valid pointer. If @slist_ptr points to a null #GSList, this does nothing.
  113. *
  114. * Since: 2.64
  115. */
  116. void
  117. g_clear_slist (GSList ** slist_ptr, GDestroyNotify destroy)
  118. {
  119. GSList *slist;
  120. slist = *slist_ptr;
  121. if (slist != NULL)
  122. {
  123. *slist_ptr = NULL;
  124. if (destroy != NULL)
  125. g_slist_free_full (slist, destroy);
  126. else
  127. g_slist_free (slist);
  128. }
  129. }
  130. /* --------------------------------------------------------------------------------------------- */
  131. /**
  132. * g_clear_list:
  133. * @list_ptr: (not nullable): a #GList return location
  134. * @destroy: (nullable): the function to pass to g_list_free_full() or NULL to not free elements
  135. *
  136. * Clears a pointer to a #GList, freeing it and, optionally, freeing its elements using @destroy.
  137. *
  138. * @list_ptr must be a valid pointer. If @list_ptr points to a null #GList, this does nothing.
  139. *
  140. * Since: 2.64
  141. */
  142. void
  143. g_clear_list (GList ** list_ptr, GDestroyNotify destroy)
  144. {
  145. GList *list;
  146. list = *list_ptr;
  147. if (list != NULL)
  148. {
  149. *list_ptr = NULL;
  150. if (destroy != NULL)
  151. g_list_free_full (list, destroy);
  152. else
  153. g_list_free (list);
  154. }
  155. }
  156. #endif /* ! GLIB_CHECK_VERSION (2, 63, 3) */
  157. /* --------------------------------------------------------------------------------------------- */
  158. #if ! GLIB_CHECK_VERSION (2, 60, 0)
  159. /**
  160. * g_queue_clear_full:
  161. * @queue: a pointer to a #GQueue
  162. * @free_func: (nullable): the function to be called to free memory allocated
  163. *
  164. * Convenience method, which frees all the memory used by a #GQueue,
  165. * and calls the provided @free_func on each item in the #GQueue.
  166. *
  167. * Since: 2.60
  168. */
  169. void
  170. g_queue_clear_full (GQueue * queue, GDestroyNotify free_func)
  171. {
  172. g_return_if_fail (queue != NULL);
  173. if (free_func != NULL)
  174. g_queue_foreach (queue, (GFunc) free_func, NULL);
  175. g_queue_clear (queue);
  176. }
  177. #endif /* ! GLIB_CHECK_VERSION (2, 60, 0) */
  178. /* --------------------------------------------------------------------------------------------- */
  179. #if ! GLIB_CHECK_VERSION (2, 77, 0)
  180. /**
  181. * g_string_new_take:
  182. * @init: (nullable): initial text used as the string.
  183. * Ownership of the string is transferred to the #GString.
  184. * Passing NULL creates an empty string.
  185. *
  186. * Creates a new #GString, initialized with the given string.
  187. *
  188. * After this call, @init belongs to the #GString and may no longer be
  189. * modified by the caller. The memory of @data has to be dynamically
  190. * allocated and will eventually be freed with g_free().
  191. *
  192. * Returns: the new #GString
  193. */
  194. GString *
  195. g_string_new_take (char *init)
  196. {
  197. GString *string;
  198. if (init == NULL)
  199. return g_string_new (NULL);
  200. string = g_slice_new (GString);
  201. string->str = init;
  202. string->len = strlen (string->str);
  203. string->allocated_len = string->len + 1;
  204. return string;
  205. }
  206. #endif /* ! GLIB_CHECK_VERSION (2, 77, 0) */
  207. /* --------------------------------------------------------------------------------------------- */
  208. /**
  209. * mc_g_string_copy:
  210. * @dest: (not nullable): the destination #GString. Its current contents are destroyed
  211. * @src: (not nullable): the source #GString
  212. * @return: @dest
  213. *
  214. * Copies the bytes from a #GString into a #GString, destroying any previous contents.
  215. * It is rather like the standard strcpy() function, except that you do not have to worry about
  216. * having enough space to copy the string.
  217. *
  218. * There is no such API in GLib2.
  219. */
  220. GString *
  221. mc_g_string_copy (GString * dest, const GString * src)
  222. {
  223. g_return_val_if_fail (src != NULL, NULL);
  224. g_return_val_if_fail (dest != NULL, NULL);
  225. g_string_set_size (dest, 0);
  226. g_string_append_len (dest, src->str, src->len);
  227. return dest;
  228. }
  229. /* --------------------------------------------------------------------------------------------- */
  230. /**
  231. * mc_g_string_dup:
  232. * @s: (nullable): the source #GString
  233. * @return: @copy of @s
  234. *
  235. * Copies the bytes from one #GString to another.
  236. *
  237. * There is no such API in GLib2.
  238. */
  239. GString *
  240. mc_g_string_dup (const GString * s)
  241. {
  242. GString *ret = NULL;
  243. if (s != NULL)
  244. ret = g_string_new_len (s->str, s->len);
  245. return ret;
  246. }
  247. /* --------------------------------------------------------------------------------------------- */