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 | |