| 1 | /* GLIB - Library of useful routines for C programming |
| 2 | * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald |
| 3 | * |
| 4 | * SPDX-License-Identifier: LGPL-2.1-or-later |
| 5 | * |
| 6 | * This library is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU Lesser General Public |
| 8 | * License as published by the Free Software Foundation; either |
| 9 | * version 2.1 of the License, or (at your option) any later version. |
| 10 | * |
| 11 | * This library 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 GNU |
| 14 | * Lesser General Public License for more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU Lesser General Public |
| 17 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. |
| 18 | */ |
| 19 | |
| 20 | /* |
| 21 | * Modified by the GLib Team and others 1997-2000. See the AUTHORS |
| 22 | * file for a list of people on the GLib Team. See the ChangeLog |
| 23 | * files for a list of changes. These files are distributed with |
| 24 | * GLib at ftp://ftp.gtk.org/pub/gtk/. |
| 25 | */ |
| 26 | |
| 27 | #ifndef __G_STRFUNCS_H__ |
| 28 | #define __G_STRFUNCS_H__ |
| 29 | |
| 30 | #if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) |
| 31 | #error "Only <glib.h> can be included directly." |
| 32 | #endif |
| 33 | |
| 34 | #include <stdarg.h> |
| 35 | #include <string.h> |
| 36 | |
| 37 | #include <glib/gmacros.h> |
| 38 | #include <glib/gtypes.h> |
| 39 | #include <glib/gerror.h> |
| 40 | #include <glib/gmem.h> |
| 41 | |
| 42 | G_BEGIN_DECLS |
| 43 | |
| 44 | /* Functions like the ones in <ctype.h> that are not affected by locale. */ |
| 45 | typedef enum { |
| 46 | G_ASCII_ALNUM = 1 << 0, |
| 47 | G_ASCII_ALPHA = 1 << 1, |
| 48 | G_ASCII_CNTRL = 1 << 2, |
| 49 | G_ASCII_DIGIT = 1 << 3, |
| 50 | G_ASCII_GRAPH = 1 << 4, |
| 51 | G_ASCII_LOWER = 1 << 5, |
| 52 | G_ASCII_PRINT = 1 << 6, |
| 53 | G_ASCII_PUNCT = 1 << 7, |
| 54 | G_ASCII_SPACE = 1 << 8, |
| 55 | G_ASCII_UPPER = 1 << 9, |
| 56 | G_ASCII_XDIGIT = 1 << 10 |
| 57 | } GAsciiType; |
| 58 | |
| 59 | GLIB_VAR const guint16 * const g_ascii_table; |
| 60 | |
| 61 | #define g_ascii_isalnum(c) \ |
| 62 | ((g_ascii_table[(guchar) (c)] & G_ASCII_ALNUM) != 0) |
| 63 | |
| 64 | #define g_ascii_isalpha(c) \ |
| 65 | ((g_ascii_table[(guchar) (c)] & G_ASCII_ALPHA) != 0) |
| 66 | |
| 67 | #define g_ascii_iscntrl(c) \ |
| 68 | ((g_ascii_table[(guchar) (c)] & G_ASCII_CNTRL) != 0) |
| 69 | |
| 70 | #define g_ascii_isdigit(c) \ |
| 71 | ((g_ascii_table[(guchar) (c)] & G_ASCII_DIGIT) != 0) |
| 72 | |
| 73 | #define g_ascii_isgraph(c) \ |
| 74 | ((g_ascii_table[(guchar) (c)] & G_ASCII_GRAPH) != 0) |
| 75 | |
| 76 | #define g_ascii_islower(c) \ |
| 77 | ((g_ascii_table[(guchar) (c)] & G_ASCII_LOWER) != 0) |
| 78 | |
| 79 | #define g_ascii_isprint(c) \ |
| 80 | ((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0) |
| 81 | |
| 82 | #define g_ascii_ispunct(c) \ |
| 83 | ((g_ascii_table[(guchar) (c)] & G_ASCII_PUNCT) != 0) |
| 84 | |
| 85 | #define g_ascii_isspace(c) \ |
| 86 | ((g_ascii_table[(guchar) (c)] & G_ASCII_SPACE) != 0) |
| 87 | |
| 88 | #define g_ascii_isupper(c) \ |
| 89 | ((g_ascii_table[(guchar) (c)] & G_ASCII_UPPER) != 0) |
| 90 | |
| 91 | #define g_ascii_isxdigit(c) \ |
| 92 | ((g_ascii_table[(guchar) (c)] & G_ASCII_XDIGIT) != 0) |
| 93 | |
| 94 | GLIB_AVAILABLE_IN_ALL |
| 95 | gchar g_ascii_tolower (gchar c) G_GNUC_CONST; |
| 96 | GLIB_AVAILABLE_IN_ALL |
| 97 | gchar g_ascii_toupper (gchar c) G_GNUC_CONST; |
| 98 | |
| 99 | GLIB_AVAILABLE_IN_ALL |
| 100 | gint g_ascii_digit_value (gchar c) G_GNUC_CONST; |
| 101 | GLIB_AVAILABLE_IN_ALL |
| 102 | gint g_ascii_xdigit_value (gchar c) G_GNUC_CONST; |
| 103 | |
| 104 | /* String utility functions that modify a string argument or |
| 105 | * return a constant string that must not be freed. |
| 106 | */ |
| 107 | #define G_STR_DELIMITERS "_-|> <." |
| 108 | GLIB_AVAILABLE_IN_ALL |
| 109 | gchar* g_strdelimit (gchar *string, |
| 110 | const gchar *delimiters, |
| 111 | gchar new_delimiter); |
| 112 | GLIB_AVAILABLE_IN_ALL |
| 113 | gchar* g_strcanon (gchar *string, |
| 114 | const gchar *valid_chars, |
| 115 | gchar substitutor); |
| 116 | GLIB_AVAILABLE_IN_ALL |
| 117 | const gchar * g_strerror (gint errnum) G_GNUC_CONST; |
| 118 | GLIB_AVAILABLE_IN_ALL |
| 119 | const gchar * g_strsignal (gint signum) G_GNUC_CONST; |
| 120 | GLIB_AVAILABLE_IN_ALL |
| 121 | gchar * g_strreverse (gchar *string); |
| 122 | GLIB_AVAILABLE_IN_ALL |
| 123 | gsize g_strlcpy (gchar *dest, |
| 124 | const gchar *src, |
| 125 | gsize dest_size); |
| 126 | GLIB_AVAILABLE_IN_ALL |
| 127 | gsize g_strlcat (gchar *dest, |
| 128 | const gchar *src, |
| 129 | gsize dest_size); |
| 130 | GLIB_AVAILABLE_IN_ALL |
| 131 | gchar * g_strstr_len (const gchar *haystack, |
| 132 | gssize haystack_len, |
| 133 | const gchar *needle); |
| 134 | GLIB_AVAILABLE_IN_ALL |
| 135 | gchar * g_strrstr (const gchar *haystack, |
| 136 | const gchar *needle); |
| 137 | GLIB_AVAILABLE_IN_ALL |
| 138 | gchar * g_strrstr_len (const gchar *haystack, |
| 139 | gssize haystack_len, |
| 140 | const gchar *needle); |
| 141 | |
| 142 | GLIB_AVAILABLE_IN_ALL |
| 143 | gboolean (g_str_has_suffix) (const gchar *str, |
| 144 | const gchar *suffix); |
| 145 | GLIB_AVAILABLE_IN_ALL |
| 146 | gboolean (g_str_has_prefix) (const gchar *str, |
| 147 | const gchar *prefix); |
| 148 | |
| 149 | #if G_GNUC_CHECK_VERSION (2, 0) |
| 150 | #ifndef __GTK_DOC_IGNORE__ |
| 151 | #ifndef __GI_SCANNER__ |
| 152 | |
| 153 | /* This macro is defeat a false -Wnonnull warning in GCC. |
| 154 | * Without it, it thinks strlen and memcmp may be getting passed NULL |
| 155 | * despite the explicit check for NULL right above the calls. |
| 156 | */ |
| 157 | #define _G_STR_NONNULL(x) ((x) + !(x)) |
| 158 | |
| 159 | #define g_str_has_prefix(STR, PREFIX) \ |
| 160 | (__builtin_constant_p (PREFIX)? \ |
| 161 | G_GNUC_EXTENSION ({ \ |
| 162 | const char * const __str = (STR); \ |
| 163 | const char * const __prefix = (PREFIX); \ |
| 164 | gboolean __result = FALSE; \ |
| 165 | \ |
| 166 | if G_UNLIKELY (__str == NULL || __prefix == NULL) \ |
| 167 | __result = (g_str_has_prefix) (__str, __prefix); \ |
| 168 | else \ |
| 169 | { \ |
| 170 | const size_t __str_len = strlen (_G_STR_NONNULL (__str)); \ |
| 171 | const size_t __prefix_len = strlen (_G_STR_NONNULL (__prefix)); \ |
| 172 | if (__str_len >= __prefix_len) \ |
| 173 | __result = memcmp (_G_STR_NONNULL (__str), \ |
| 174 | _G_STR_NONNULL (__prefix), \ |
| 175 | __prefix_len) == 0; \ |
| 176 | } \ |
| 177 | __result; \ |
| 178 | }) \ |
| 179 | : \ |
| 180 | (g_str_has_prefix) (STR, PREFIX) \ |
| 181 | ) |
| 182 | |
| 183 | #define g_str_has_suffix(STR, SUFFIX) \ |
| 184 | (__builtin_constant_p (SUFFIX)? \ |
| 185 | G_GNUC_EXTENSION ({ \ |
| 186 | const char * const __str = (STR); \ |
| 187 | const char * const __suffix = (SUFFIX); \ |
| 188 | gboolean __result = FALSE; \ |
| 189 | \ |
| 190 | if G_UNLIKELY (__str == NULL || __suffix == NULL) \ |
| 191 | __result = (g_str_has_suffix) (__str, __suffix); \ |
| 192 | else \ |
| 193 | { \ |
| 194 | const size_t __str_len = strlen (_G_STR_NONNULL (__str)); \ |
| 195 | const size_t __suffix_len = strlen (_G_STR_NONNULL (__suffix)); \ |
| 196 | if (__str_len >= __suffix_len) \ |
| 197 | __result = memcmp (__str + __str_len - __suffix_len, \ |
| 198 | _G_STR_NONNULL (__suffix), \ |
| 199 | __suffix_len) == 0; \ |
| 200 | } \ |
| 201 | __result; \ |
| 202 | }) \ |
| 203 | : \ |
| 204 | (g_str_has_suffix) (STR, SUFFIX) \ |
| 205 | ) |
| 206 | |
| 207 | #endif /* !defined (__GI_SCANNER__) */ |
| 208 | #endif /* !defined (__GTK_DOC_IGNORE__) */ |
| 209 | #endif /* G_GNUC_CHECK_VERSION (2, 0) */ |
| 210 | |
| 211 | /* String to/from double conversion functions */ |
| 212 | |
| 213 | GLIB_AVAILABLE_IN_ALL |
| 214 | gdouble g_strtod (const gchar *nptr, |
| 215 | gchar **endptr); |
| 216 | GLIB_AVAILABLE_IN_ALL |
| 217 | gdouble g_ascii_strtod (const gchar *nptr, |
| 218 | gchar **endptr); |
| 219 | GLIB_AVAILABLE_IN_ALL |
| 220 | guint64 g_ascii_strtoull (const gchar *nptr, |
| 221 | gchar **endptr, |
| 222 | guint base); |
| 223 | GLIB_AVAILABLE_IN_ALL |
| 224 | gint64 g_ascii_strtoll (const gchar *nptr, |
| 225 | gchar **endptr, |
| 226 | guint base); |
| 227 | /* 29 bytes should enough for all possible values that |
| 228 | * g_ascii_dtostr can produce. |
| 229 | * Then add 10 for good measure */ |
| 230 | #define G_ASCII_DTOSTR_BUF_SIZE (29 + 10) |
| 231 | GLIB_AVAILABLE_IN_ALL |
| 232 | gchar * g_ascii_dtostr (gchar *buffer, |
| 233 | gint buf_len, |
| 234 | gdouble d); |
| 235 | GLIB_AVAILABLE_IN_ALL |
| 236 | gchar * g_ascii_formatd (gchar *buffer, |
| 237 | gint buf_len, |
| 238 | const gchar *format, |
| 239 | gdouble d); |
| 240 | |
| 241 | /* removes leading spaces */ |
| 242 | GLIB_AVAILABLE_IN_ALL |
| 243 | gchar* g_strchug (gchar *string); |
| 244 | /* removes trailing spaces */ |
| 245 | GLIB_AVAILABLE_IN_ALL |
| 246 | gchar* g_strchomp (gchar *string); |
| 247 | /* removes leading & trailing spaces */ |
| 248 | #define g_strstrip( string ) g_strchomp (g_strchug (string)) |
| 249 | |
| 250 | GLIB_AVAILABLE_IN_ALL |
| 251 | gint g_ascii_strcasecmp (const gchar *s1, |
| 252 | const gchar *s2); |
| 253 | GLIB_AVAILABLE_IN_ALL |
| 254 | gint g_ascii_strncasecmp (const gchar *s1, |
| 255 | const gchar *s2, |
| 256 | gsize n); |
| 257 | GLIB_AVAILABLE_IN_ALL |
| 258 | gchar* g_ascii_strdown (const gchar *str, |
| 259 | gssize len) G_GNUC_MALLOC; |
| 260 | GLIB_AVAILABLE_IN_ALL |
| 261 | gchar* g_ascii_strup (const gchar *str, |
| 262 | gssize len) G_GNUC_MALLOC; |
| 263 | |
| 264 | GLIB_AVAILABLE_IN_2_40 |
| 265 | gboolean g_str_is_ascii (const gchar *str); |
| 266 | |
| 267 | GLIB_DEPRECATED |
| 268 | gint g_strcasecmp (const gchar *s1, |
| 269 | const gchar *s2); |
| 270 | GLIB_DEPRECATED |
| 271 | gint g_strncasecmp (const gchar *s1, |
| 272 | const gchar *s2, |
| 273 | guint n); |
| 274 | GLIB_DEPRECATED |
| 275 | gchar* g_strdown (gchar *string); |
| 276 | GLIB_DEPRECATED |
| 277 | gchar* g_strup (gchar *string); |
| 278 | |
| 279 | |
| 280 | /* String utility functions that return a newly allocated string which |
| 281 | * ought to be freed with g_free from the caller at some point. |
| 282 | */ |
| 283 | GLIB_AVAILABLE_IN_ALL |
| 284 | gchar* (g_strdup) (const gchar *str) G_GNUC_MALLOC; |
| 285 | GLIB_AVAILABLE_IN_ALL |
| 286 | gchar* g_strdup_printf (const gchar *format, |
| 287 | ...) G_GNUC_PRINTF (1, 2) G_GNUC_MALLOC; |
| 288 | GLIB_AVAILABLE_IN_ALL |
| 289 | gchar* g_strdup_vprintf (const gchar *format, |
| 290 | va_list args) G_GNUC_PRINTF(1, 0) G_GNUC_MALLOC; |
| 291 | GLIB_AVAILABLE_IN_ALL |
| 292 | gchar* g_strndup (const gchar *str, |
| 293 | gsize n) G_GNUC_MALLOC; |
| 294 | GLIB_AVAILABLE_IN_ALL |
| 295 | gchar* g_strnfill (gsize length, |
| 296 | gchar fill_char) G_GNUC_MALLOC; |
| 297 | GLIB_AVAILABLE_IN_ALL |
| 298 | gchar* g_strconcat (const gchar *string1, |
| 299 | ...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED; |
| 300 | GLIB_AVAILABLE_IN_ALL |
| 301 | gchar* g_strjoin (const gchar *separator, |
| 302 | ...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED; |
| 303 | |
| 304 | #if G_GNUC_CHECK_VERSION(2, 0) |
| 305 | #ifndef __GTK_DOC_IGNORE__ |
| 306 | #ifndef __GI_SCANNER__ |
| 307 | |
| 308 | G_ALWAYS_INLINE static inline char * |
| 309 | g_strdup_inline (const char *str) |
| 310 | { |
| 311 | if (__builtin_constant_p (!str) && !str) |
| 312 | return NULL; |
| 313 | |
| 314 | if (__builtin_constant_p (!!str) && !!str && __builtin_constant_p (strlen (s: str))) |
| 315 | { |
| 316 | const size_t len = strlen (s: str) + 1; |
| 317 | char *dup_str = (char *) g_malloc (n_bytes: len); |
| 318 | return (char *) memcpy (dest: dup_str, src: str, n: len); |
| 319 | } |
| 320 | |
| 321 | return g_strdup (str); |
| 322 | } |
| 323 | |
| 324 | #define g_strdup(x) g_strdup_inline (x) |
| 325 | |
| 326 | #endif /* !defined (__GI_SCANNER__) */ |
| 327 | #endif /* !defined (__GTK_DOC_IGNORE__) */ |
| 328 | #endif /* G_GNUC_CHECK_VERSION (2, 0) */ |
| 329 | |
| 330 | /* Make a copy of a string interpreting C string -style escape |
| 331 | * sequences. Inverse of g_strescape. The recognized sequences are \b |
| 332 | * \f \n \r \t \\ \" and the octal format. |
| 333 | */ |
| 334 | GLIB_AVAILABLE_IN_ALL |
| 335 | gchar* g_strcompress (const gchar *source) G_GNUC_MALLOC; |
| 336 | |
| 337 | /* Copy a string escaping nonprintable characters like in C strings. |
| 338 | * Inverse of g_strcompress. The exceptions parameter, if non-NULL, points |
| 339 | * to a string containing characters that are not to be escaped. |
| 340 | * |
| 341 | * Deprecated API: gchar* g_strescape (const gchar *source); |
| 342 | * Luckily this function wasn't used much, using NULL as second parameter |
| 343 | * provides mostly identical semantics. |
| 344 | */ |
| 345 | GLIB_AVAILABLE_IN_ALL |
| 346 | gchar* g_strescape (const gchar *source, |
| 347 | const gchar *exceptions) G_GNUC_MALLOC; |
| 348 | |
| 349 | GLIB_DEPRECATED_IN_2_68_FOR (g_memdup2) |
| 350 | gpointer g_memdup (gconstpointer mem, |
| 351 | guint byte_size) G_GNUC_ALLOC_SIZE(2); |
| 352 | |
| 353 | GLIB_AVAILABLE_IN_2_68 |
| 354 | gpointer g_memdup2 (gconstpointer mem, |
| 355 | gsize byte_size) G_GNUC_ALLOC_SIZE(2); |
| 356 | |
| 357 | /* NULL terminated string arrays. |
| 358 | * g_strsplit(), g_strsplit_set() split up string into max_tokens tokens |
| 359 | * at delim and return a newly allocated string array. |
| 360 | * g_strjoinv() concatenates all of str_array's strings, sliding in an |
| 361 | * optional separator, the returned string is newly allocated. |
| 362 | * g_strfreev() frees the array itself and all of its strings. |
| 363 | * g_strdupv() copies a NULL-terminated array of strings |
| 364 | * g_strv_length() returns the length of a NULL-terminated array of strings |
| 365 | */ |
| 366 | typedef gchar** GStrv; |
| 367 | GLIB_AVAILABLE_IN_ALL |
| 368 | gchar** g_strsplit (const gchar *string, |
| 369 | const gchar *delimiter, |
| 370 | gint max_tokens); |
| 371 | GLIB_AVAILABLE_IN_ALL |
| 372 | gchar ** g_strsplit_set (const gchar *string, |
| 373 | const gchar *delimiters, |
| 374 | gint max_tokens); |
| 375 | GLIB_AVAILABLE_IN_ALL |
| 376 | gchar* g_strjoinv (const gchar *separator, |
| 377 | gchar **str_array) G_GNUC_MALLOC; |
| 378 | GLIB_AVAILABLE_IN_ALL |
| 379 | void g_strfreev (gchar **str_array); |
| 380 | GLIB_AVAILABLE_IN_ALL |
| 381 | gchar** g_strdupv (gchar **str_array); |
| 382 | GLIB_AVAILABLE_IN_ALL |
| 383 | guint g_strv_length (gchar **str_array); |
| 384 | |
| 385 | GLIB_AVAILABLE_IN_ALL |
| 386 | gchar* g_stpcpy (gchar *dest, |
| 387 | const char *src); |
| 388 | |
| 389 | GLIB_AVAILABLE_IN_2_40 |
| 390 | gchar * g_str_to_ascii (const gchar *str, |
| 391 | const gchar *from_locale); |
| 392 | |
| 393 | GLIB_AVAILABLE_IN_2_40 |
| 394 | gchar ** g_str_tokenize_and_fold (const gchar *string, |
| 395 | const gchar *translit_locale, |
| 396 | gchar ***ascii_alternates); |
| 397 | |
| 398 | GLIB_AVAILABLE_IN_2_40 |
| 399 | gboolean g_str_match_string (const gchar *search_term, |
| 400 | const gchar *potential_hit, |
| 401 | gboolean accept_alternates); |
| 402 | |
| 403 | GLIB_AVAILABLE_IN_2_44 |
| 404 | gboolean g_strv_contains (const gchar * const *strv, |
| 405 | const gchar *str); |
| 406 | |
| 407 | GLIB_AVAILABLE_IN_2_60 |
| 408 | gboolean g_strv_equal (const gchar * const *strv1, |
| 409 | const gchar * const *strv2); |
| 410 | |
| 411 | /* Convenience ASCII string to number API */ |
| 412 | |
| 413 | /** |
| 414 | * GNumberParserError: |
| 415 | * @G_NUMBER_PARSER_ERROR_INVALID: string was not a valid number |
| 416 | * @G_NUMBER_PARSER_ERROR_OUT_OF_BOUNDS: string was a number, but out of bounds |
| 417 | * |
| 418 | * Error codes returned by functions converting a string to a number. |
| 419 | * |
| 420 | * Since: 2.54 |
| 421 | */ |
| 422 | typedef enum |
| 423 | { |
| 424 | G_NUMBER_PARSER_ERROR_INVALID, |
| 425 | G_NUMBER_PARSER_ERROR_OUT_OF_BOUNDS, |
| 426 | } GNumberParserError; |
| 427 | |
| 428 | /** |
| 429 | * G_NUMBER_PARSER_ERROR: |
| 430 | * |
| 431 | * Domain for errors returned by functions converting a string to a |
| 432 | * number. |
| 433 | * |
| 434 | * Since: 2.54 |
| 435 | */ |
| 436 | #define G_NUMBER_PARSER_ERROR (g_number_parser_error_quark ()) |
| 437 | |
| 438 | GLIB_AVAILABLE_IN_2_54 |
| 439 | GQuark g_number_parser_error_quark (void); |
| 440 | |
| 441 | GLIB_AVAILABLE_IN_2_54 |
| 442 | gboolean g_ascii_string_to_signed (const gchar *str, |
| 443 | guint base, |
| 444 | gint64 min, |
| 445 | gint64 max, |
| 446 | gint64 *out_num, |
| 447 | GError **error); |
| 448 | |
| 449 | GLIB_AVAILABLE_IN_2_54 |
| 450 | gboolean g_ascii_string_to_unsigned (const gchar *str, |
| 451 | guint base, |
| 452 | guint64 min, |
| 453 | guint64 max, |
| 454 | guint64 *out_num, |
| 455 | GError **error); |
| 456 | |
| 457 | /** |
| 458 | * g_set_str: (skip) |
| 459 | * @str_pointer: (inout) (not optional) (nullable): a pointer to either |
| 460 | * a string or `NULL` |
| 461 | * @new_str: (nullable): a string to assign to @str_pointer |
| 462 | * |
| 463 | * Updates a pointer to a string to a copy of @new_str and returns whether the |
| 464 | * string was changed. |
| 465 | * |
| 466 | * If @new_str matches the previous string, this function is a no-op. If |
| 467 | * @new_str is different, a copy of it will be assigned to @str_pointer and |
| 468 | * the previous string pointed to by @str_pointer will be freed with |
| 469 | * [func@GLib.free]. |
| 470 | * |
| 471 | * @str_pointer must not be `NULL`, but can point to a `NULL` value. |
| 472 | * |
| 473 | * One convenient usage of this function is in implementing property settings: |
| 474 | * ```C |
| 475 | * void |
| 476 | * foo_set_bar (Foo *foo, |
| 477 | * const char *new_bar) |
| 478 | * { |
| 479 | * g_return_if_fail (IS_FOO (foo)); |
| 480 | * |
| 481 | * if (g_set_str (&foo->bar, new_bar)) |
| 482 | * g_object_notify (foo, "bar"); |
| 483 | * } |
| 484 | * ``` |
| 485 | * |
| 486 | * Returns: true if the value of @str_pointer changed, false otherwise |
| 487 | * |
| 488 | * Since: 2.76 |
| 489 | */ |
| 490 | GLIB_AVAILABLE_STATIC_INLINE_IN_2_76 |
| 491 | static inline gboolean |
| 492 | g_set_str (char **str_pointer, |
| 493 | const char *new_str) |
| 494 | { |
| 495 | char *copy; |
| 496 | |
| 497 | if (*str_pointer == new_str || |
| 498 | (*str_pointer && new_str && strcmp (s1: *str_pointer, s2: new_str) == 0)) |
| 499 | return FALSE; |
| 500 | |
| 501 | copy = g_strdup (new_str); |
| 502 | g_free (mem: *str_pointer); |
| 503 | *str_pointer = copy; |
| 504 | |
| 505 | return TRUE; |
| 506 | } |
| 507 | |
| 508 | G_END_DECLS |
| 509 | |
| 510 | #endif /* __G_STRFUNCS_H__ */ |
| 511 | |