1 /* Unit tests for utilities
2 * Copyright (C) 2010 Red Hat, Inc.
4 * SPDX-License-Identifier: LicenseRef-old-glib-tests
6 * This work is provided "as is"; redistribution and modification
7 * in whole or in part, in any medium, physical or electronic is
8 * permitted without restriction.
10 * This work is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * In no event shall the authors or contributors be liable for any
15 * direct, indirect, incidental, special, exemplary, or consequential
16 * damages (including, but not limited to, procurement of substitute
17 * goods or services; loss of use, data, or profits; or business
18 * interruption) however caused and on any theory of liability, whether
19 * in contract, strict liability, or tort (including negligence or
20 * otherwise) arising in any way out of the use of this software, even
21 * if advised of the possibility of such damage.
23 * Author: Matthias Clasen
26 #ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
27 #define GLIB_DISABLE_DEPRECATION_WARNINGS
31 #include "glib-private.h"
32 #include "gutilsprivate.h"
33 #include "glib/gstdio.h"
39 #include <sys/utsname.h>
46 strv_check (const gchar * const *strv, ...)
52 va_start (args, strv);
53 for (i = 0; strv[i]; i++)
55 s = va_arg (args, gchar*);
56 if (g_strcmp0 (strv[i], s) != 0)
69 test_language_names (void)
71 const gchar * const *names;
73 g_setenv ("LANGUAGE", "de:en_US", TRUE);
74 names = g_get_language_names ();
75 g_assert (strv_check (names, "de", "en_US", "en", "C", NULL));
77 g_setenv ("LANGUAGE", "tt_RU.UTF-8@iqtelif", TRUE);
78 names = g_get_language_names ();
79 g_assert (strv_check (names,
80 "tt_RU.UTF-8@iqtelif",
93 test_locale_variants (void)
97 v = g_get_locale_variants ("fr_BE");
98 g_assert (strv_check ((const gchar * const *) v, "fr_BE", "fr", NULL));
101 v = g_get_locale_variants ("sr_SR@latin");
102 g_assert (strv_check ((const gchar * const *) v, "sr_SR@latin", "sr@latin", "sr_SR", "sr", NULL));
109 if (g_test_verbose ())
110 g_printerr ("(header %d.%d.%d library %d.%d.%d) ",
111 GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION,
112 glib_major_version, glib_minor_version, glib_micro_version);
114 g_assert (glib_check_version (GLIB_MAJOR_VERSION,
116 GLIB_MICRO_VERSION) == NULL);
117 g_assert (glib_check_version (GLIB_MAJOR_VERSION,
120 g_assert (glib_check_version (GLIB_MAJOR_VERSION - 1,
123 g_assert (glib_check_version (GLIB_MAJOR_VERSION + 1,
126 g_assert (glib_check_version (GLIB_MAJOR_VERSION,
127 GLIB_MINOR_VERSION + 1,
129 /* don't use + 1 here, since a +/-1 difference can
130 * happen due to post-release version bumps in git
132 g_assert (glib_check_version (GLIB_MAJOR_VERSION,
134 GLIB_MICRO_VERSION + 3) != NULL);
137 static const gchar *argv0;
142 const gchar *prgname;
143 const gchar *appname;
145 prgname = g_get_prgname ();
146 appname = g_get_application_name ();
147 g_assert_cmpstr (prgname, ==, argv0);
148 g_assert_cmpstr (appname, ==, prgname);
150 g_set_prgname ("prgname");
152 prgname = g_get_prgname ();
153 appname = g_get_application_name ();
154 g_assert_cmpstr (prgname, ==, "prgname");
155 g_assert_cmpstr (appname, ==, "prgname");
157 g_set_application_name ("appname");
159 prgname = g_get_prgname ();
160 appname = g_get_application_name ();
161 g_assert_cmpstr (prgname, ==, "prgname");
162 g_assert_cmpstr (appname, ==, "appname");
166 thread_prgname_check (gpointer data)
168 gint *n_threads_got_prgname = (gint *) data;
169 const gchar *old_prgname;
171 old_prgname = g_get_prgname ();
172 g_assert_cmpstr (old_prgname, ==, "prgname");
174 g_atomic_int_inc (n_threads_got_prgname);
176 while (g_strcmp0 (g_get_prgname (), "prgname2") != 0);
182 test_prgname_thread_safety (void)
185 gint n_threads_got_prgname;
188 g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/847");
189 g_test_summary ("Test that threads racing to get and set the program name "
190 "always receive a valid program name.");
192 g_set_prgname ("prgname");
193 g_atomic_int_set (&n_threads_got_prgname, 0);
195 for (i = 0; i < G_N_ELEMENTS (threads); i++)
196 threads[i] = g_thread_new (NULL, thread_prgname_check, &n_threads_got_prgname);
198 while (g_atomic_int_get (&n_threads_got_prgname) != G_N_ELEMENTS (threads))
201 g_set_prgname ("prgname2");
203 /* Wait for all the workers to exit. */
204 for (i = 0; i < G_N_ELEMENTS (threads); i++)
205 g_thread_join (threads[i]);
208 g_set_prgname ("prgname");
216 g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=627969");
217 g_test_summary ("Test that g_get_tmp_dir() returns a correct default if TMPDIR is set to the empty string");
219 if (g_test_subprocess ())
221 g_assert_cmpstr (g_get_tmp_dir (), !=, "");
225 envp = g_get_environ ();
227 envp = g_environ_setenv (g_steal_pointer (&envp), "TMPDIR", "", TRUE);
228 envp = g_environ_unsetenv (g_steal_pointer (&envp), "TMP");
229 envp = g_environ_unsetenv (g_steal_pointer (&envp), "TEMP");
231 g_test_trap_subprocess_with_envp (NULL, (const gchar * const *) envp,
232 0, G_TEST_SUBPROCESS_DEFAULT);
233 g_test_trap_assert_passed ();
237 #if defined(__GNUC__) && (__GNUC__ >= 4)
238 #define TEST_BUILTINS 1
240 #define TEST_BUILTINS 0
245 builtin_bit_nth_lsf1 (gulong mask, gint nth_bit)
249 if (G_LIKELY (nth_bit < GLIB_SIZEOF_LONG * 8 - 1))
250 mask &= -(1UL << (nth_bit + 1));
254 return __builtin_ffsl (mask) - 1;
258 builtin_bit_nth_lsf2 (gulong mask, gint nth_bit)
262 if (G_LIKELY (nth_bit < GLIB_SIZEOF_LONG * 8 - 1))
263 mask &= -(1UL << (nth_bit + 1));
267 return mask ? __builtin_ctzl (mask) : -1;
271 builtin_bit_nth_msf (gulong mask, gint nth_bit)
273 if (nth_bit >= 0 && nth_bit < GLIB_SIZEOF_LONG * 8)
274 mask &= (1UL << nth_bit) - 1;
275 return mask ? GLIB_SIZEOF_LONG * 8 - 1 - __builtin_clzl (mask) : -1;
279 builtin_bit_storage (gulong number)
281 return number ? GLIB_SIZEOF_LONG * 8 - __builtin_clzl (number) : 1;
286 naive_bit_nth_lsf (gulong mask, gint nth_bit)
288 if (G_UNLIKELY (nth_bit < -1))
290 while (nth_bit < ((GLIB_SIZEOF_LONG * 8) - 1))
293 if (mask & (1UL << nth_bit))
300 naive_bit_nth_msf (gulong mask, gint nth_bit)
302 if (nth_bit < 0 || G_UNLIKELY (nth_bit > GLIB_SIZEOF_LONG * 8))
303 nth_bit = GLIB_SIZEOF_LONG * 8;
307 if (mask & (1UL << nth_bit))
314 naive_bit_storage (gulong number)
328 test_basic_bits (void)
333 /* we loop like this: 0, -1, 1, -2, 2, -3, 3, ... */
334 for (i = 0; (glong) i < 1500; i = -(i + ((glong) i >= 0)))
336 guint naive_bit_storage_i = naive_bit_storage (i);
338 /* Test the g_bit_*() implementations against the compiler builtins (if
339 * available), and against a slow-but-correct ‘naive’ implementation.
340 * They should all agree.
342 * The macro and function versions of the g_bit_*() functions are tested,
343 * hence one call with the function name in brackets (to avoid it being
344 * expanded as a macro). */
346 g_assert_cmpint (naive_bit_storage_i, ==, builtin_bit_storage (i));
348 g_assert_cmpint (naive_bit_storage_i, ==, g_bit_storage (i));
349 g_assert_cmpint (naive_bit_storage_i, ==, (g_bit_storage) (i));
351 for (nth_bit = -3; nth_bit <= 2 + GLIB_SIZEOF_LONG * 8; nth_bit++)
353 gint naive_bit_nth_lsf_i_nth_bit = naive_bit_nth_lsf (i, nth_bit);
354 gint naive_bit_nth_msf_i_nth_bit = naive_bit_nth_msf (i, nth_bit);
357 g_assert_cmpint (naive_bit_nth_lsf_i_nth_bit, ==,
358 builtin_bit_nth_lsf1 (i, nth_bit));
359 g_assert_cmpint (naive_bit_nth_lsf_i_nth_bit, ==,
360 builtin_bit_nth_lsf2 (i, nth_bit));
362 g_assert_cmpint (naive_bit_nth_lsf_i_nth_bit, ==,
363 g_bit_nth_lsf (i, nth_bit));
364 g_assert_cmpint (naive_bit_nth_lsf_i_nth_bit, ==,
365 (g_bit_nth_lsf) (i, nth_bit));
368 g_assert_cmpint (naive_bit_nth_msf_i_nth_bit, ==,
369 builtin_bit_nth_msf (i, nth_bit));
371 g_assert_cmpint (naive_bit_nth_msf_i_nth_bit, ==,
372 g_bit_nth_msf (i, nth_bit));
373 g_assert_cmpint (naive_bit_nth_msf_i_nth_bit, ==,
374 (g_bit_nth_msf) (i, nth_bit));
386 pos = g_bit_nth_lsf (0, -1);
387 g_assert_cmpint (pos, ==, -1);
389 max_bit = sizeof (gulong) * 8;
390 for (i = 0; i < max_bit; i++)
394 pos = g_bit_nth_lsf (mask, -1);
395 g_assert_cmpint (pos, ==, i);
397 pos = g_bit_nth_lsf (mask, i - 3);
398 g_assert_cmpint (pos , ==, i);
400 pos = g_bit_nth_lsf (mask, i);
401 g_assert_cmpint (pos , ==, -1);
403 pos = g_bit_nth_lsf (mask, i + 1);
404 g_assert_cmpint (pos , ==, -1);
407 pos = g_bit_nth_msf (0, -1);
408 g_assert_cmpint (pos, ==, -1);
410 for (i = 0; i < max_bit; i++)
414 pos = g_bit_nth_msf (mask, -1);
415 g_assert_cmpint (pos, ==, i);
417 pos = g_bit_nth_msf (mask, i + 3);
418 g_assert_cmpint (pos , ==, i);
420 pos = g_bit_nth_msf (mask, i);
421 g_assert_cmpint (pos , ==, -1);
425 pos = g_bit_nth_msf (mask, i - 1);
426 g_assert_cmpint (pos , ==, -1);
441 g_assert_cmpint (GUINT16_SWAP_LE_BE (a16), ==, b16);
446 g_assert_cmpint (GUINT32_SWAP_LE_BE (a32), ==, b32);
448 a64 = G_GUINT64_CONSTANT(0xaaaaaaaabbbbbbbb);
449 b64 = G_GUINT64_CONSTANT(0xbbbbbbbbaaaaaaaa);
451 g_assert_cmpint (GUINT64_SWAP_LE_BE (a64), ==, b64);
455 test_find_program (void)
460 gchar *relative_path;
461 gchar *absolute_path;
465 res = g_find_program_in_path ("sh");
466 g_assert (res != NULL);
469 res = g_find_program_in_path ("/bin/sh");
470 g_assert (res != NULL);
473 /* Resolve any symlinks in the CWD as that breaks the test e.g.
474 * with the FreeBSD /home/ -> /usr/home symlink. */
475 cwd = realpath (".", NULL);
476 absolute_path = g_find_program_in_path ("sh");
477 relative_path = g_strdup (absolute_path);
478 for (i = 0; cwd[i] != '\0'; i++)
480 if (cwd[i] == '/' && cwd[i + 1] != '\0')
482 gchar *relative_path_2 = g_strconcat ("../", relative_path, NULL);
483 g_free (relative_path);
484 relative_path = relative_path_2;
487 res = g_find_program_in_path (relative_path);
488 g_assert_nonnull (res);
489 g_assert_true (g_path_is_absolute (res));
491 g_free (absolute_path);
492 g_free (relative_path);
496 /* There's not a lot we can search for that would reliably work both
497 * on real Windows and mingw.
501 res = g_find_program_in_path ("this_program_does_not_exit");
502 g_assert (res == NULL);
504 res = g_find_program_in_path ("/bin");
505 g_assert (res == NULL);
507 res = g_find_program_in_path ("/etc/passwd");
508 g_assert (res == NULL);
512 find_program_for_path (const char *program,
514 const char *working_dir)
516 return GLIB_PRIVATE_CALL(g_find_program_for_path) (program, path, working_dir);
520 test_find_program_for_path (void)
522 GError *error = NULL;
523 /* Using .cmd extension to make windows to consider it an executable */
524 const char *command_to_find = "just-an-exe-file.cmd";
531 tmp = g_dir_make_tmp ("find_program_for_path_XXXXXXX", &error);
532 g_assert_no_error (error);
534 path = g_build_filename (tmp, "sub-path", NULL);
535 g_mkdir (path, 0700);
536 g_assert_true (g_file_test (path, G_FILE_TEST_IS_DIR));
538 exe_path = g_build_filename (path, command_to_find, NULL);
539 g_file_set_contents (exe_path, "", -1, &error);
540 g_assert_no_error (error);
541 g_assert_true (g_file_test (exe_path, G_FILE_TEST_EXISTS));
544 g_assert_no_errno (g_chmod (exe_path, 0500));
546 g_assert_true (g_file_test (exe_path, G_FILE_TEST_IS_EXECUTABLE));
548 g_assert_null (g_find_program_in_path (command_to_find));
549 g_assert_null (find_program_for_path (command_to_find, NULL, NULL));
551 found_path = find_program_for_path (command_to_find, path, NULL);
553 g_assert_nonnull (found_path);
554 g_assert_true (g_str_has_suffix (found_path, exe_path));
556 g_assert_cmpstr (exe_path, ==, found_path);
558 g_clear_pointer (&found_path, g_free);
560 found_path = find_program_for_path (command_to_find, path, path);
562 g_assert_nonnull (found_path);
563 g_assert_true (g_str_has_suffix (found_path, exe_path));
565 g_assert_cmpstr (exe_path, ==, found_path);
567 g_clear_pointer (&found_path, g_free);
569 found_path = find_program_for_path (command_to_find, NULL, path);
571 g_assert_nonnull (found_path);
572 g_assert_true (g_str_has_suffix (found_path, exe_path));
574 g_assert_cmpstr (exe_path, ==, found_path);
576 g_clear_pointer (&found_path, g_free);
578 found_path = find_program_for_path (command_to_find, "::", path);
580 g_assert_nonnull (found_path);
581 g_assert_true (g_str_has_suffix (found_path, exe_path));
583 g_assert_cmpstr (exe_path, ==, found_path);
585 g_clear_pointer (&found_path, g_free);
587 old_cwd = g_get_current_dir ();
590 find_program_for_path (command_to_find,
591 G_SEARCHPATH_SEPARATOR_S G_SEARCHPATH_SEPARATOR_S, NULL);
593 g_clear_pointer (&old_cwd, g_free);
595 g_assert_nonnull (found_path);
596 g_assert_true (g_str_has_suffix (found_path, exe_path));
598 g_assert_cmpstr (exe_path, ==, found_path);
600 g_clear_pointer (&found_path, g_free);
602 old_cwd = g_get_current_dir ();
605 find_program_for_path (command_to_find,
606 G_SEARCHPATH_SEPARATOR_S G_SEARCHPATH_SEPARATOR_S, "sub-path");
608 g_clear_pointer (&old_cwd, g_free);
610 g_assert_nonnull (found_path);
611 g_assert_true (g_str_has_suffix (found_path, exe_path));
613 g_assert_cmpstr (exe_path, ==, found_path);
615 g_clear_pointer (&found_path, g_free);
618 find_program_for_path (command_to_find,
619 G_SEARCHPATH_SEPARATOR_S G_SEARCHPATH_SEPARATOR_S, "other-sub-path"));
621 found_path = find_program_for_path (command_to_find,
622 G_SEARCHPATH_SEPARATOR_S "sub-path" G_SEARCHPATH_SEPARATOR_S, tmp);
624 g_assert_nonnull (found_path);
625 g_assert_true (g_str_has_suffix (found_path, exe_path));
627 g_assert_cmpstr (exe_path, ==, found_path);
629 g_clear_pointer (&found_path, g_free);
631 g_assert_null (find_program_for_path (command_to_find,
632 G_SEARCHPATH_SEPARATOR_S "other-sub-path" G_SEARCHPATH_SEPARATOR_S, tmp));
635 found_path = find_program_for_path ("sh", NULL, tmp);
636 g_assert_nonnull (found_path);
637 g_clear_pointer (&found_path, g_free);
639 old_cwd = g_get_current_dir ();
641 found_path = find_program_for_path ("sh", "sbin:bin:usr/bin:usr/sbin", NULL);
643 g_clear_pointer (&old_cwd, g_free);
644 g_assert_nonnull (found_path);
645 g_clear_pointer (&found_path, g_free);
647 found_path = find_program_for_path ("sh", "sbin:bin:usr/bin:usr/sbin", "/");
648 g_assert_nonnull (found_path);
649 g_clear_pointer (&found_path, g_free);
650 #endif /* G_OS_UNIX */
652 g_clear_pointer (&exe_path, g_free);
653 g_clear_pointer (&path, g_free);
654 g_clear_pointer (&tmp, g_free);
655 g_clear_error (&error);
668 res = g_parse_debug_string (NULL, keys, G_N_ELEMENTS (keys));
669 g_assert_cmpint (res, ==, 0);
671 res = g_parse_debug_string ("foobabla;#!%!$%112 223", keys, G_N_ELEMENTS (keys));
672 g_assert_cmpint (res, ==, 0);
674 res = g_parse_debug_string ("key1:key2", keys, G_N_ELEMENTS (keys));
675 g_assert_cmpint (res, ==, 3);
677 res = g_parse_debug_string ("key1;key2", keys, G_N_ELEMENTS (keys));
678 g_assert_cmpint (res, ==, 3);
680 res = g_parse_debug_string ("key1,key2", keys, G_N_ELEMENTS (keys));
681 g_assert_cmpint (res, ==, 3);
683 res = g_parse_debug_string ("key1 key2", keys, G_N_ELEMENTS (keys));
684 g_assert_cmpint (res, ==, 3);
686 res = g_parse_debug_string ("key1\tkey2", keys, G_N_ELEMENTS (keys));
687 g_assert_cmpint (res, ==, 3);
689 res = g_parse_debug_string ("all", keys, G_N_ELEMENTS (keys));
690 g_assert_cmpint (res, ==, 7);
692 if (g_test_subprocess ())
694 res = g_parse_debug_string ("help", keys, G_N_ELEMENTS (keys));
695 g_assert_cmpint (res, ==, 0);
698 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
699 g_test_trap_assert_passed ();
700 g_test_trap_assert_stderr ("*Supported debug values: key1 key2 key3 all help*");
709 c = g_get_codeset ();
712 g_assert_cmpstr (c, ==, c2);
720 if (g_test_subprocess ())
723 g_setenv ("CHARSET", "UTF-8", TRUE);
725 g_assert_cmpstr (c, ==, "UTF-8");
728 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
729 g_test_trap_assert_passed ();
733 test_console_charset (void)
739 /* store current environment and unset $LANG to make sure it does not interfere */
740 const unsigned int initial_cp = GetConsoleOutputCP ();
741 gchar *initial_lang = g_strdup (g_getenv ("LANG"));
744 /* set console output codepage to something specific (ISO-8859-1 aka CP28591) and query it */
745 SetConsoleOutputCP (28591);
746 g_get_console_charset (&c1);
747 g_assert_cmpstr (c1, ==, "ISO-8859-1");
749 /* set $LANG to something specific (should override the console output codepage) and query it */
750 g_setenv ("LANG", "de_DE.ISO-8859-15@euro", TRUE);
751 g_get_console_charset (&c2);
752 g_assert_cmpstr (c2, ==, "ISO-8859-15");
754 /* reset environment */
756 SetConsoleOutputCP (initial_cp);
758 g_setenv ("LANG", initial_lang, TRUE);
759 g_free (initial_lang);
762 g_get_console_charset (&c2);
764 g_assert_cmpstr (c1, ==, c2);
768 extern const gchar *glib_pgettext (const gchar *msgidctxt, gsize msgidoffset);
773 const gchar *am0, *am1, *am2, *am3;
775 am0 = glib_pgettext ("GDateTime\004AM", strlen ("GDateTime") + 1);
776 am1 = g_dpgettext ("glib20", "GDateTime\004AM", strlen ("GDateTime") + 1);
777 am2 = g_dpgettext ("glib20", "GDateTime|AM", 0);
778 am3 = g_dpgettext2 ("glib20", "GDateTime", "AM");
780 g_assert_cmpstr (am0, ==, am1);
781 g_assert_cmpstr (am1, ==, am2);
782 g_assert_cmpstr (am2, ==, am3);
790 name = g_get_user_name ();
792 g_assert (name != NULL);
800 name = g_get_real_name ();
802 g_assert (name != NULL);
810 name = g_get_host_name ();
812 g_assert (name != NULL);
813 g_assert_true (g_utf8_validate (name, -1, NULL));
822 const gchar * const *dirs;
825 xdg = g_strdup (g_getenv ("XDG_CONFIG_HOME"));
827 xdg = g_build_filename (g_get_home_dir (), ".config", NULL);
829 dir = g_get_user_config_dir ();
831 g_assert_cmpstr (dir, ==, xdg);
834 xdg = g_strdup (g_getenv ("XDG_DATA_HOME"));
836 xdg = g_build_filename (g_get_home_dir (), ".local", "share", NULL);
838 dir = g_get_user_data_dir ();
840 g_assert_cmpstr (dir, ==, xdg);
843 xdg = g_strdup (g_getenv ("XDG_CACHE_HOME"));
845 xdg = g_build_filename (g_get_home_dir (), ".cache", NULL);
847 dir = g_get_user_cache_dir ();
849 g_assert_cmpstr (dir, ==, xdg);
852 xdg = g_strdup (g_getenv ("XDG_STATE_HOME"));
854 xdg = g_build_filename (g_get_home_dir (), ".local/state", NULL);
856 dir = g_get_user_state_dir ();
858 g_assert_cmpstr (dir, ==, xdg);
861 xdg = g_strdup (g_getenv ("XDG_RUNTIME_DIR"));
863 xdg = g_strdup (g_get_user_cache_dir ());
865 dir = g_get_user_runtime_dir ();
867 g_assert_cmpstr (dir, ==, xdg);
870 xdg = (gchar *)g_getenv ("XDG_CONFIG_DIRS");
874 dirs = g_get_system_config_dirs ();
876 s = g_strjoinv (":", (gchar **)dirs);
878 g_assert_cmpstr (s, ==, xdg);
885 test_special_dir (void)
887 const gchar *dir, *dir2;
889 dir = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
890 g_reload_user_special_dirs_cache ();
891 dir2 = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
893 g_assert_cmpstr (dir, ==, dir2);
897 test_desktop_special_dir (void)
899 const gchar *dir, *dir2;
901 dir = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
902 g_assert (dir != NULL);
904 g_reload_user_special_dirs_cache ();
905 dir2 = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
906 g_assert (dir2 != NULL);
913 gchar *contents = NULL;
914 #if defined (G_OS_UNIX) && !(defined (G_OS_WIN32) || defined (__APPLE__))
918 /* Whether this is implemented or not, it must not crash */
919 name = g_get_os_info (G_OS_INFO_KEY_NAME);
920 g_test_message ("%s: %s",
922 name == NULL ? "(null)" : name);
924 #if defined (G_OS_WIN32) || defined (__APPLE__)
925 /* These OSs have a special case so NAME should always succeed */
926 g_assert_nonnull (name);
927 #elif defined (G_OS_UNIX)
928 if (g_file_get_contents ("/etc/os-release", &contents, NULL, NULL) ||
929 g_file_get_contents ("/usr/lib/os-release", &contents, NULL, NULL) ||
931 g_assert_nonnull (name);
933 g_test_skip ("os-release(5) API not implemented on this platform");
935 g_test_skip ("g_get_os_info() not supported on this platform");
943 source_test (gpointer data)
945 g_assert_not_reached ();
949 test_clear_source (void)
953 id = g_idle_add_once (source_test, NULL);
954 g_assert_cmpuint (id, >, 0);
956 g_clear_handle_id (&id, g_source_remove);
957 g_assert_cmpuint (id, ==, 0);
959 id = g_timeout_add_once (100, source_test, NULL);
960 g_assert_cmpuint (id, >, 0);
962 g_clear_handle_id (&id, g_source_remove);
963 g_assert_cmpuint (id, ==, 0);
967 test_clear_pointer (void)
972 g_clear_pointer (&a, g_free);
973 g_assert (a == NULL);
976 (g_clear_pointer) (&a, g_free);
977 g_assert (a == NULL);
980 /* Test that g_clear_pointer() works with a GDestroyNotify which contains a cast.
981 * See https://gitlab.gnome.org/GNOME/glib/issues/1425 */
983 test_clear_pointer_cast (void)
985 GHashTable *hash_table = NULL;
987 hash_table = g_hash_table_new (g_str_hash, g_str_equal);
989 g_assert_nonnull (hash_table);
991 g_clear_pointer (&hash_table, (void (*) (GHashTable *)) g_hash_table_destroy);
993 g_assert_null (hash_table);
996 /* Test that the macro version of g_clear_pointer() only evaluates its argument
997 * once, just like the function version would. */
999 test_clear_pointer_side_effects (void)
1001 gchar **my_string_array, **i;
1003 my_string_array = g_new0 (gchar*, 3);
1004 my_string_array[0] = g_strdup ("hello");
1005 my_string_array[1] = g_strdup ("there");
1006 my_string_array[2] = NULL;
1008 i = my_string_array;
1010 g_clear_pointer (i++, g_free);
1012 g_assert_true (i == &my_string_array[1]);
1013 g_assert_null (my_string_array[0]);
1014 g_assert_nonnull (my_string_array[1]);
1015 g_assert_null (my_string_array[2]);
1017 g_free (my_string_array[1]);
1018 g_free (my_string_array[2]);
1019 g_free (my_string_array);
1022 static int obj_count;
1025 get_obj (gpointer *obj_out)
1027 gpointer obj = g_malloc (5);
1031 *obj_out = g_steal_pointer (&obj);
1041 test_take_pointer (void)
1051 /* ensure that it works to skip the macro */
1052 b = (g_steal_pointer) (&a);
1057 g_assert (!obj_count);
1061 test_misc_mem (void)
1065 a = g_try_malloc (0);
1066 g_assert (a == NULL);
1068 a = g_try_malloc0 (0);
1069 g_assert (a == NULL);
1072 a = g_try_realloc (a, 20);
1073 a = g_try_realloc (a, 0);
1075 g_assert (a == NULL);
1079 aligned_alloc_nz (void)
1083 /* Test an alignment that’s zero */
1084 a = g_aligned_alloc (16, sizeof(char), 0);
1090 aligned_alloc_npot (void)
1094 /* Test an alignment that’s not a power of two */
1095 a = g_aligned_alloc (16, sizeof(char), 15);
1101 aligned_alloc_nmov (void)
1105 /* Test an alignment that’s not a multiple of sizeof(void*) */
1106 a = g_aligned_alloc (16, sizeof(char), sizeof(void *) / 2);
1112 test_aligned_mem (void)
1116 g_test_summary ("Aligned memory allocator");
1118 a = g_aligned_alloc (0, sizeof (int), MAX (sizeof (void *), 8));
1121 a = g_aligned_alloc0 (0, sizeof (int), MAX (sizeof (void *), 8));
1124 a = g_aligned_alloc (16, 0, MAX (sizeof (void *), 8));
1127 #define CHECK_SUBPROCESS_FAIL(name,msg) do { \
1128 if (g_test_undefined ()) \
1130 g_test_message (msg); \
1131 g_test_trap_subprocess ("/utils/aligned-mem/subprocess/" #name, 0, \
1132 G_TEST_SUBPROCESS_DEFAULT); \
1133 g_test_trap_assert_failed (); \
1137 CHECK_SUBPROCESS_FAIL (aligned_alloc_nz, "Alignment must not be zero");
1138 CHECK_SUBPROCESS_FAIL (aligned_alloc_npot, "Alignment must be a power of two");
1139 CHECK_SUBPROCESS_FAIL (aligned_alloc_nmov, "Alignment must be a multiple of sizeof(void*)");
1143 test_aligned_mem_alignment (void)
1147 g_test_summary ("Check that g_aligned_alloc() returns a correctly aligned pointer");
1149 p = g_aligned_alloc (5, sizeof (*p), 256);
1150 g_assert_nonnull (p);
1151 g_assert_cmpuint (((guintptr) p) % 256, ==, 0);
1157 test_aligned_mem_zeroed (void)
1159 gsize n_blocks = 10;
1163 g_test_summary ("Check that g_aligned_alloc0() zeroes out its allocation");
1165 p = g_aligned_alloc0 (n_blocks, sizeof (*p), 16);
1166 g_assert_nonnull (p);
1168 for (i = 0; i < n_blocks; i++)
1169 g_assert_cmpuint (p[i], ==, 0);
1175 test_aligned_mem_free_sized (void)
1177 gsize n_blocks = 10;
1180 g_test_summary ("Check that g_aligned_free_sized() works");
1182 p = g_aligned_alloc (n_blocks, sizeof (*p), 16);
1183 g_assert_nonnull (p);
1185 g_aligned_free_sized (p, sizeof (*p), n_blocks * 16);
1187 /* NULL should be ignored */
1188 g_aligned_free_sized (NULL, sizeof (*p), n_blocks * 16);
1192 test_free_sized (void)
1196 g_test_summary ("Check that g_free_sized() works");
1199 g_assert_nonnull (p);
1201 g_free_sized (p, 123);
1203 /* NULL should be ignored */
1204 g_free_sized (NULL, 123);
1210 gpointer p = &test_nullify;
1212 g_assert (p != NULL);
1214 g_nullify_pointer (&p);
1216 g_assert (p == NULL);
1222 g_print ("atexit called");
1228 if (g_test_subprocess ())
1230 g_atexit (atexit_func);
1233 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
1234 g_test_trap_assert_passed ();
1235 g_test_trap_assert_stdout ("*atexit called*");
1239 test_check_setuid (void)
1243 res = GLIB_PRIVATE_CALL(g_check_setuid) ();
1247 /* Test the defined integer limits are correct, as some compilers have had
1248 * problems with signed/unsigned conversion in the past. These limits should not
1249 * vary between platforms, compilers or architectures.
1251 * Use string comparisons to avoid the same systematic problems with unary minus
1252 * application in C++. See https://gitlab.gnome.org/GNOME/glib/issues/1663. */
1254 test_int_limits (void)
1258 g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1663");
1260 str = g_strdup_printf ("%d %d %u\n"
1261 "%" G_GINT16_FORMAT " %" G_GINT16_FORMAT " %" G_GUINT16_FORMAT "\n"
1262 "%" G_GINT32_FORMAT " %" G_GINT32_FORMAT " %" G_GUINT32_FORMAT "\n"
1263 "%" G_GINT64_FORMAT " %" G_GINT64_FORMAT " %" G_GUINT64_FORMAT "\n",
1264 G_MININT8, G_MAXINT8, G_MAXUINT8,
1265 G_MININT16, G_MAXINT16, G_MAXUINT16,
1266 G_MININT32, G_MAXINT32, G_MAXUINT32,
1267 G_MININT64, G_MAXINT64, G_MAXUINT64);
1269 g_assert_cmpstr (str, ==,
1271 "-32768 32767 65535\n"
1272 "-2147483648 2147483647 4294967295\n"
1273 "-9223372036854775808 9223372036854775807 18446744073709551615\n");
1278 test_clear_list (void)
1282 g_clear_list (&list, NULL);
1283 g_assert_null (list);
1285 list = g_list_prepend (list, "test");
1286 g_assert_nonnull (list);
1288 g_clear_list (&list, NULL);
1289 g_assert_null (list);
1291 g_clear_list (&list, g_free);
1292 g_assert_null (list);
1294 list = g_list_prepend (list, g_malloc (16));
1295 g_assert_nonnull (list);
1297 g_clear_list (&list, g_free);
1298 g_assert_null (list);
1302 test_clear_slist (void)
1304 GSList *slist = NULL;
1306 g_clear_slist (&slist, NULL);
1307 g_assert_null (slist);
1309 slist = g_slist_prepend (slist, "test");
1310 g_assert_nonnull (slist);
1312 g_clear_slist (&slist, NULL);
1313 g_assert_null (slist);
1315 g_clear_slist (&slist, g_free);
1316 g_assert_null (slist);
1318 slist = g_slist_prepend (slist, g_malloc (16));
1319 g_assert_nonnull (slist);
1321 g_clear_slist (&slist, g_free);
1322 g_assert_null (slist);
1331 /* g_test_init() only calls g_set_prgname() if g_get_prgname()
1332 * returns %NULL, but g_get_prgname() on Windows never returns NULL.
1333 * So we need to do this by hand to make test_appname() work on
1336 g_set_prgname (argv[0]);
1338 g_test_init (&argc, &argv, NULL);
1340 g_test_add_func ("/utils/language-names", test_language_names);
1341 g_test_add_func ("/utils/locale-variants", test_locale_variants);
1342 g_test_add_func ("/utils/version", test_version);
1343 g_test_add_func ("/utils/appname", test_appname);
1344 g_test_add_func ("/utils/prgname-thread-safety", test_prgname_thread_safety);
1345 g_test_add_func ("/utils/tmpdir", test_tmpdir);
1346 g_test_add_func ("/utils/basic_bits", test_basic_bits);
1347 g_test_add_func ("/utils/bits", test_bits);
1348 g_test_add_func ("/utils/swap", test_swap);
1349 g_test_add_func ("/utils/find-program", test_find_program);
1350 g_test_add_func ("/utils/find-program-for-path", test_find_program_for_path);
1351 g_test_add_func ("/utils/debug", test_debug);
1352 g_test_add_func ("/utils/codeset", test_codeset);
1353 g_test_add_func ("/utils/codeset2", test_codeset2);
1354 g_test_add_func ("/utils/console-charset", test_console_charset);
1355 g_test_add_func ("/utils/gettext", test_gettext);
1356 g_test_add_func ("/utils/username", test_username);
1357 g_test_add_func ("/utils/realname", test_realname);
1358 g_test_add_func ("/utils/hostname", test_hostname);
1360 g_test_add_func ("/utils/xdgdirs", test_xdg_dirs);
1362 g_test_add_func ("/utils/specialdir", test_special_dir);
1363 g_test_add_func ("/utils/specialdir/desktop", test_desktop_special_dir);
1364 g_test_add_func ("/utils/os-info", test_os_info);
1365 g_test_add_func ("/utils/clear-pointer", test_clear_pointer);
1366 g_test_add_func ("/utils/clear-pointer-cast", test_clear_pointer_cast);
1367 g_test_add_func ("/utils/clear-pointer/side-effects", test_clear_pointer_side_effects);
1368 g_test_add_func ("/utils/take-pointer", test_take_pointer);
1369 g_test_add_func ("/utils/clear-source", test_clear_source);
1370 g_test_add_func ("/utils/misc-mem", test_misc_mem);
1371 g_test_add_func ("/utils/aligned-mem", test_aligned_mem);
1372 g_test_add_func ("/utils/aligned-mem/subprocess/aligned_alloc_nz", aligned_alloc_nz);
1373 g_test_add_func ("/utils/aligned-mem/subprocess/aligned_alloc_npot", aligned_alloc_npot);
1374 g_test_add_func ("/utils/aligned-mem/subprocess/aligned_alloc_nmov", aligned_alloc_nmov);
1375 g_test_add_func ("/utils/aligned-mem/alignment", test_aligned_mem_alignment);
1376 g_test_add_func ("/utils/aligned-mem/zeroed", test_aligned_mem_zeroed);
1377 g_test_add_func ("/utils/aligned-mem/free-sized", test_aligned_mem_free_sized);
1378 g_test_add_func ("/utils/free-sized", test_free_sized);
1379 g_test_add_func ("/utils/nullify", test_nullify);
1380 g_test_add_func ("/utils/atexit", test_atexit);
1381 g_test_add_func ("/utils/check-setuid", test_check_setuid);
1382 g_test_add_func ("/utils/int-limits", test_int_limits);
1383 g_test_add_func ("/utils/clear-list", test_clear_list);
1384 g_test_add_func ("/utils/clear-slist", test_clear_slist);
1386 return g_test_run ();