1/* Unit tests for utilities
2 * Copyright (C) 2010 Red Hat, Inc.
3 *
4 * This work is provided "as is"; redistribution and modification
5 * in whole or in part, in any medium, physical or electronic is
6 * permitted without restriction.
7 *
8 * This work is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * In no event shall the authors or contributors be liable for any
13 * direct, indirect, incidental, special, exemplary, or consequential
14 * damages (including, but not limited to, procurement of substitute
15 * goods or services; loss of use, data, or profits; or business
16 * interruption) however caused and on any theory of liability, whether
17 * in contract, strict liability, or tort (including negligence or
18 * otherwise) arising in any way out of the use of this software, even
19 * if advised of the possibility of such damage.
20 *
21 * Author: Matthias Clasen
22 */
23
24#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
25#define GLIB_DISABLE_DEPRECATION_WARNINGS
26#endif
27
28#include "glib.h"
29#include "glib-private.h"
30
31#include <stdlib.h>
32#include <string.h>
33#include <stdarg.h>
34#ifdef G_OS_UNIX
35#include <sys/utsname.h>
36#endif
37#ifdef G_OS_WIN32
38#include <windows.h>
39#endif
40
41static gboolean
42strv_check (const gchar * const *strv, ...)
43{
44 va_list args;
45 gchar *s;
46 gint i;
47
48 va_start (args, strv);
49 for (i = 0; strv[i]; i++)
50 {
51 s = va_arg (args, gchar*);
52 if (g_strcmp0 (str1: strv[i], str2: s) != 0)
53 {
54 va_end (args);
55 return FALSE;
56 }
57 }
58
59 va_end (args);
60
61 return TRUE;
62}
63
64static void
65test_language_names (void)
66{
67 const gchar * const *names;
68
69 g_setenv (variable: "LANGUAGE", value: "de:en_US", TRUE);
70 names = g_get_language_names ();
71 g_assert (strv_check (names, "de", "en_US", "en", "C", NULL));
72
73 g_setenv (variable: "LANGUAGE", value: "tt_RU.UTF-8@iqtelif", TRUE);
74 names = g_get_language_names ();
75 g_assert (strv_check (names,
76 "tt_RU.UTF-8@iqtelif",
77 "tt_RU@iqtelif",
78 "tt.UTF-8@iqtelif",
79 "tt@iqtelif",
80 "tt_RU.UTF-8",
81 "tt_RU",
82 "tt.UTF-8",
83 "tt",
84 "C",
85 NULL));
86}
87
88static void
89test_locale_variants (void)
90{
91 char **v;
92
93 v = g_get_locale_variants (locale: "fr_BE");
94 g_assert (strv_check ((const gchar * const *) v, "fr_BE", "fr", NULL));
95 g_strfreev (str_array: v);
96
97 v = g_get_locale_variants (locale: "sr_SR@latin");
98 g_assert (strv_check ((const gchar * const *) v, "sr_SR@latin", "sr@latin", "sr_SR", "sr", NULL));
99 g_strfreev (str_array: v);
100}
101
102static void
103test_version (void)
104{
105 if (g_test_verbose ())
106 g_printerr (format: "(header %d.%d.%d library %d.%d.%d) ",
107 GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION,
108 glib_major_version, glib_minor_version, glib_micro_version);
109
110 g_assert (glib_check_version (GLIB_MAJOR_VERSION,
111 GLIB_MINOR_VERSION,
112 GLIB_MICRO_VERSION) == NULL);
113 g_assert (glib_check_version (GLIB_MAJOR_VERSION,
114 GLIB_MINOR_VERSION,
115 0) == NULL);
116 g_assert (glib_check_version (GLIB_MAJOR_VERSION - 1,
117 0,
118 0) != NULL);
119 g_assert (glib_check_version (GLIB_MAJOR_VERSION + 1,
120 0,
121 0) != NULL);
122 g_assert (glib_check_version (GLIB_MAJOR_VERSION,
123 GLIB_MINOR_VERSION + 1,
124 0) != NULL);
125 /* don't use + 1 here, since a +/-1 difference can
126 * happen due to post-release version bumps in git
127 */
128 g_assert (glib_check_version (GLIB_MAJOR_VERSION,
129 GLIB_MINOR_VERSION,
130 GLIB_MICRO_VERSION + 3) != NULL);
131}
132
133static const gchar *argv0;
134
135static void
136test_appname (void)
137{
138 const gchar *prgname;
139 const gchar *appname;
140
141 prgname = g_get_prgname ();
142 appname = g_get_application_name ();
143 g_assert_cmpstr (prgname, ==, argv0);
144 g_assert_cmpstr (appname, ==, prgname);
145
146 g_set_prgname (prgname: "prgname");
147
148 prgname = g_get_prgname ();
149 appname = g_get_application_name ();
150 g_assert_cmpstr (prgname, ==, "prgname");
151 g_assert_cmpstr (appname, ==, "prgname");
152
153 g_set_application_name (application_name: "appname");
154
155 prgname = g_get_prgname ();
156 appname = g_get_application_name ();
157 g_assert_cmpstr (prgname, ==, "prgname");
158 g_assert_cmpstr (appname, ==, "appname");
159}
160
161static void
162test_tmpdir (void)
163{
164 g_test_bug (bug_uri_snippet: "627969");
165 g_assert_cmpstr (g_get_tmp_dir (), !=, "");
166}
167
168static void
169test_bits (void)
170{
171 gulong mask;
172 gint max_bit;
173 gint i, pos;
174
175 pos = g_bit_nth_lsf (0, -1);
176 g_assert_cmpint (pos, ==, -1);
177
178 max_bit = sizeof (gulong) * 8;
179 for (i = 0; i < max_bit; i++)
180 {
181 mask = 1UL << i;
182
183 pos = g_bit_nth_lsf (mask, -1);
184 g_assert_cmpint (pos, ==, i);
185
186 pos = g_bit_nth_lsf (mask, i - 3);
187 g_assert_cmpint (pos , ==, i);
188
189 pos = g_bit_nth_lsf (mask, i);
190 g_assert_cmpint (pos , ==, -1);
191
192 pos = g_bit_nth_lsf (mask, i + 1);
193 g_assert_cmpint (pos , ==, -1);
194 }
195
196 pos = g_bit_nth_msf (0, -1);
197 g_assert_cmpint (pos, ==, -1);
198
199 for (i = 0; i < max_bit; i++)
200 {
201 mask = 1UL << i;
202
203 pos = g_bit_nth_msf (mask, -1);
204 g_assert_cmpint (pos, ==, i);
205
206 pos = g_bit_nth_msf (mask, i + 3);
207 g_assert_cmpint (pos , ==, i);
208
209 pos = g_bit_nth_msf (mask, i);
210 g_assert_cmpint (pos , ==, -1);
211
212 if (i > 0)
213 {
214 pos = g_bit_nth_msf (mask, i - 1);
215 g_assert_cmpint (pos , ==, -1);
216 }
217 }
218}
219
220static void
221test_swap (void)
222{
223 guint16 a16, b16;
224 guint32 a32, b32;
225 guint64 a64, b64;
226
227 a16 = 0xaabb;
228 b16 = 0xbbaa;
229
230 g_assert_cmpint (GUINT16_SWAP_LE_BE (a16), ==, b16);
231
232 a32 = 0xaaaabbbb;
233 b32 = 0xbbbbaaaa;
234
235 g_assert_cmpint (GUINT32_SWAP_LE_BE (a32), ==, b32);
236
237 a64 = G_GUINT64_CONSTANT(0xaaaaaaaabbbbbbbb);
238 b64 = G_GUINT64_CONSTANT(0xbbbbbbbbaaaaaaaa);
239
240 g_assert_cmpint (GUINT64_SWAP_LE_BE (a64), ==, b64);
241}
242
243static void
244test_find_program (void)
245{
246 gchar *res;
247
248#ifdef G_OS_UNIX
249 res = g_find_program_in_path (program: "sh");
250 g_assert (res != NULL);
251 g_free (mem: res);
252
253 res = g_find_program_in_path (program: "/bin/sh");
254 g_assert (res != NULL);
255 g_free (mem: res);
256#else
257 /* There's not a lot we can search for that would reliably work both
258 * on real Windows and mingw.
259 */
260#endif
261
262 res = g_find_program_in_path (program: "this_program_does_not_exit");
263 g_assert (res == NULL);
264
265 res = g_find_program_in_path (program: "/bin");
266 g_assert (res == NULL);
267
268 res = g_find_program_in_path (program: "/etc/passwd");
269 g_assert (res == NULL);
270}
271
272static void
273test_debug (void)
274{
275 GDebugKey keys[] = {
276 { "key1", 1 },
277 { "key2", 2 },
278 { "key3", 4 },
279 };
280 guint res;
281
282 res = g_parse_debug_string (NULL, keys, G_N_ELEMENTS (keys));
283 g_assert_cmpint (res, ==, 0);
284
285 res = g_parse_debug_string (string: "foobabla;#!%!$%112 223", keys, G_N_ELEMENTS (keys));
286 g_assert_cmpint (res, ==, 0);
287
288 res = g_parse_debug_string (string: "key1:key2", keys, G_N_ELEMENTS (keys));
289 g_assert_cmpint (res, ==, 3);
290
291 res = g_parse_debug_string (string: "key1;key2", keys, G_N_ELEMENTS (keys));
292 g_assert_cmpint (res, ==, 3);
293
294 res = g_parse_debug_string (string: "key1,key2", keys, G_N_ELEMENTS (keys));
295 g_assert_cmpint (res, ==, 3);
296
297 res = g_parse_debug_string (string: "key1 key2", keys, G_N_ELEMENTS (keys));
298 g_assert_cmpint (res, ==, 3);
299
300 res = g_parse_debug_string (string: "key1\tkey2", keys, G_N_ELEMENTS (keys));
301 g_assert_cmpint (res, ==, 3);
302
303 res = g_parse_debug_string (string: "all", keys, G_N_ELEMENTS (keys));
304 g_assert_cmpint (res, ==, 7);
305
306 if (g_test_subprocess ())
307 {
308 res = g_parse_debug_string (string: "help", keys, G_N_ELEMENTS (keys));
309 g_assert_cmpint (res, ==, 0);
310 return;
311 }
312 g_test_trap_subprocess (NULL, usec_timeout: 0, test_flags: 0);
313 g_test_trap_assert_passed ();
314 g_test_trap_assert_stderr ("*Supported debug values: key1 key2 key3 all help*");
315}
316
317static void
318test_codeset (void)
319{
320 gchar *c;
321 const gchar *c2;
322
323 c = g_get_codeset ();
324 g_get_charset (charset: &c2);
325
326 g_assert_cmpstr (c, ==, c2);
327
328 g_free (mem: c);
329}
330
331static void
332test_codeset2 (void)
333{
334 if (g_test_subprocess ())
335 {
336 const gchar *c;
337 g_setenv (variable: "CHARSET", value: "UTF-8", TRUE);
338 g_get_charset (charset: &c);
339 g_assert_cmpstr (c, ==, "UTF-8");
340 return;
341 }
342 g_test_trap_subprocess (NULL, usec_timeout: 0, test_flags: 0);
343 g_test_trap_assert_passed ();
344}
345
346static void
347test_console_charset (void)
348{
349 const gchar *c1;
350 const gchar *c2;
351
352#ifdef G_OS_WIN32
353 /* store current environment and unset $LANG to make sure it does not interfere */
354 const unsigned int initial_cp = GetConsoleOutputCP ();
355 gchar *initial_lang = g_strdup (g_getenv ("LANG"));
356 g_unsetenv ("LANG");
357
358 /* set console output codepage to something specific (ISO-8859-1 aka CP28591) and query it */
359 SetConsoleOutputCP (28591);
360 g_get_console_charset (&c1);
361 g_assert_cmpstr (c1, ==, "ISO-8859-1");
362
363 /* set $LANG to something specific (should override the console output codepage) and query it */
364 g_setenv ("LANG", "de_DE.ISO-8859-15@euro", TRUE);
365 g_get_console_charset (&c2);
366 g_assert_cmpstr (c2, ==, "ISO-8859-15");
367
368 /* reset environment */
369 if (initial_cp)
370 SetConsoleOutputCP (initial_cp);
371 if (initial_lang)
372 g_setenv ("LANG", initial_lang, TRUE);
373 g_free (initial_lang);
374#else
375 g_get_charset (charset: &c1);
376 g_get_console_charset (charset: &c2);
377
378 g_assert_cmpstr (c1, ==, c2);
379#endif
380}
381
382static void
383test_basename (void)
384{
385 const gchar *path = "/path/to/a/file/deep/down.sh";
386 const gchar *b;
387
388 b = g_basename (file_name: path);
389
390 g_assert_cmpstr (b, ==, "down.sh");
391}
392
393extern const gchar *glib_pgettext (const gchar *msgidctxt, gsize msgidoffset);
394
395static void
396test_gettext (void)
397{
398 const gchar *am0, *am1, *am2, *am3;
399
400 am0 = glib_pgettext (msgidctxt: "GDateTime\004AM", msgidoffset: strlen (s: "GDateTime") + 1);
401 am1 = g_dpgettext (domain: "glib20", msgctxtid: "GDateTime\004AM", msgidoffset: strlen (s: "GDateTime") + 1);
402 am2 = g_dpgettext (domain: "glib20", msgctxtid: "GDateTime|AM", msgidoffset: 0);
403 am3 = g_dpgettext2 (domain: "glib20", context: "GDateTime", msgid: "AM");
404
405 g_assert_cmpstr (am0, ==, am1);
406 g_assert_cmpstr (am1, ==, am2);
407 g_assert_cmpstr (am2, ==, am3);
408}
409
410static void
411test_username (void)
412{
413 const gchar *name;
414
415 name = g_get_user_name ();
416
417 g_assert (name != NULL);
418}
419
420static void
421test_realname (void)
422{
423 const gchar *name;
424
425 name = g_get_real_name ();
426
427 g_assert (name != NULL);
428}
429
430static void
431test_hostname (void)
432{
433 const gchar *name;
434
435 name = g_get_host_name ();
436
437 g_assert (name != NULL);
438 g_assert_true (g_utf8_validate (name, -1, NULL));
439}
440
441#ifdef G_OS_UNIX
442static void
443test_xdg_dirs (void)
444{
445 gchar *xdg;
446 const gchar *dir;
447 const gchar * const *dirs;
448 gchar *s;
449
450 xdg = g_strdup (str: g_getenv (variable: "XDG_CONFIG_HOME"));
451 if (!xdg)
452 xdg = g_build_filename (first_element: g_get_home_dir (), ".config", NULL);
453
454 dir = g_get_user_config_dir ();
455
456 g_assert_cmpstr (dir, ==, xdg);
457 g_free (mem: xdg);
458
459 xdg = g_strdup (str: g_getenv (variable: "XDG_DATA_HOME"));
460 if (!xdg)
461 xdg = g_build_filename (first_element: g_get_home_dir (), ".local", "share", NULL);
462
463 dir = g_get_user_data_dir ();
464
465 g_assert_cmpstr (dir, ==, xdg);
466 g_free (mem: xdg);
467
468 xdg = g_strdup (str: g_getenv (variable: "XDG_CACHE_HOME"));
469 if (!xdg)
470 xdg = g_build_filename (first_element: g_get_home_dir (), ".cache", NULL);
471
472 dir = g_get_user_cache_dir ();
473
474 g_assert_cmpstr (dir, ==, xdg);
475 g_free (mem: xdg);
476
477 xdg = g_strdup (str: g_getenv (variable: "XDG_RUNTIME_DIR"));
478 if (!xdg)
479 xdg = g_strdup (str: g_get_user_cache_dir ());
480
481 dir = g_get_user_runtime_dir ();
482
483 g_assert_cmpstr (dir, ==, xdg);
484 g_free (mem: xdg);
485
486 xdg = (gchar *)g_getenv (variable: "XDG_CONFIG_DIRS");
487 if (!xdg)
488 xdg = "/etc/xdg";
489
490 dirs = g_get_system_config_dirs ();
491
492 s = g_strjoinv (separator: ":", str_array: (gchar **)dirs);
493
494 g_assert_cmpstr (s, ==, xdg);
495
496 g_free (mem: s);
497}
498#endif
499
500static void
501test_special_dir (void)
502{
503 const gchar *dir, *dir2;
504
505 dir = g_get_user_special_dir (directory: G_USER_DIRECTORY_DESKTOP);
506 g_reload_user_special_dirs_cache ();
507 dir2 = g_get_user_special_dir (directory: G_USER_DIRECTORY_DESKTOP);
508
509 g_assert_cmpstr (dir, ==, dir2);
510}
511
512static void
513test_desktop_special_dir (void)
514{
515 const gchar *dir, *dir2;
516
517 dir = g_get_user_special_dir (directory: G_USER_DIRECTORY_DESKTOP);
518 g_assert (dir != NULL);
519
520 g_reload_user_special_dirs_cache ();
521 dir2 = g_get_user_special_dir (directory: G_USER_DIRECTORY_DESKTOP);
522 g_assert (dir2 != NULL);
523}
524
525static void
526test_os_info (void)
527{
528 gchar *name;
529 gchar *contents = NULL;
530#ifdef G_OS_UNIX
531 struct utsname info;
532#endif
533
534 /* Whether this is implemented or not, it must not crash */
535 name = g_get_os_info (G_OS_INFO_KEY_NAME);
536 g_test_message (format: "%s: %s",
537 G_OS_INFO_KEY_NAME,
538 name == NULL ? "(null)" : name);
539
540#if defined (G_OS_WIN32) || defined (__APPLE__)
541 /* These OSs have a special case so NAME should always succeed */
542 g_assert_nonnull (name);
543#elif defined (G_OS_UNIX)
544 if (g_file_get_contents (filename: "/etc/os-release", contents: &contents, NULL, NULL) ||
545 g_file_get_contents (filename: "/usr/lib/os-release", contents: &contents, NULL, NULL) ||
546 uname (name: &info) == 0)
547 g_assert_nonnull (name);
548 else
549 g_test_skip (msg: "os-release(5) API not implemented on this platform");
550#else
551 g_test_skip ("g_get_os_info() not supported on this platform");
552#endif
553
554 g_free (mem: name);
555 g_free (mem: contents);
556}
557
558static gboolean
559source_test (gpointer data)
560{
561 g_assert_not_reached ();
562 return G_SOURCE_REMOVE;
563}
564
565static void
566test_clear_source (void)
567{
568 guint id;
569
570 id = g_idle_add (function: source_test, NULL);
571 g_assert_cmpuint (id, >, 0);
572
573 g_clear_handle_id (&id, g_source_remove);
574 g_assert_cmpuint (id, ==, 0);
575
576 id = g_timeout_add (interval: 100, function: source_test, NULL);
577 g_assert_cmpuint (id, >, 0);
578
579 g_clear_handle_id (&id, g_source_remove);
580 g_assert_cmpuint (id, ==, 0);
581}
582
583static void
584test_clear_pointer (void)
585{
586 gpointer a;
587
588 a = g_malloc (n_bytes: 5);
589 g_clear_pointer (&a, g_free);
590 g_assert (a == NULL);
591
592 a = g_malloc (n_bytes: 5);
593 (g_clear_pointer) (pp: &a, destroy: g_free);
594 g_assert (a == NULL);
595}
596
597/* Test that g_clear_pointer() works with a GDestroyNotify which contains a cast.
598 * See https://gitlab.gnome.org/GNOME/glib/issues/1425 */
599static void
600test_clear_pointer_cast (void)
601{
602 GHashTable *hash_table = NULL;
603
604 hash_table = g_hash_table_new (hash_func: g_str_hash, key_equal_func: g_str_equal);
605
606 g_assert_nonnull (hash_table);
607
608 g_clear_pointer (&hash_table, (void (*) (GHashTable *)) g_hash_table_destroy);
609
610 g_assert_null (hash_table);
611}
612
613/* Test that the macro version of g_clear_pointer() only evaluates its argument
614 * once, just like the function version would. */
615static void
616test_clear_pointer_side_effects (void)
617{
618 gchar **my_string_array, **i;
619
620 my_string_array = g_new0 (gchar*, 3);
621 my_string_array[0] = g_strdup (str: "hello");
622 my_string_array[1] = g_strdup (str: "there");
623 my_string_array[2] = NULL;
624
625 i = my_string_array;
626
627 g_clear_pointer (i++, g_free);
628
629 g_assert_true (i == &my_string_array[1]);
630 g_assert_null (my_string_array[0]);
631 g_assert_nonnull (my_string_array[1]);
632 g_assert_null (my_string_array[2]);
633
634 g_free (mem: my_string_array[1]);
635 g_free (mem: my_string_array[2]);
636 g_free (mem: my_string_array);
637}
638
639static int obj_count;
640
641static void
642get_obj (gpointer *obj_out)
643{
644 gpointer obj = g_malloc (n_bytes: 5);
645 obj_count++;
646
647 if (obj_out)
648 *obj_out = g_steal_pointer (&obj);
649
650 if (obj)
651 {
652 g_free (mem: obj);
653 obj_count--;
654 }
655}
656
657static void
658test_take_pointer (void)
659{
660 gpointer a;
661 gpointer b;
662
663 get_obj (NULL);
664
665 get_obj (obj_out: &a);
666 g_assert (a);
667
668 /* ensure that it works to skip the macro */
669 b = (g_steal_pointer) (pp: &a);
670 g_assert (!a);
671 obj_count--;
672 g_free (mem: b);
673
674 g_assert (!obj_count);
675}
676
677static void
678test_misc_mem (void)
679{
680 gpointer a;
681
682 a = g_try_malloc (n_bytes: 0);
683 g_assert (a == NULL);
684
685 a = g_try_malloc0 (n_bytes: 0);
686 g_assert (a == NULL);
687
688 a = g_malloc (n_bytes: 16);
689 a = g_try_realloc (mem: a, n_bytes: 20);
690 a = g_try_realloc (mem: a, n_bytes: 0);
691
692 g_assert (a == NULL);
693}
694
695static void
696test_nullify (void)
697{
698 gpointer p = &test_nullify;
699
700 g_assert (p != NULL);
701
702 g_nullify_pointer (nullify_location: &p);
703
704 g_assert (p == NULL);
705}
706
707static void
708atexit_func (void)
709{
710 g_print (format: "atexit called");
711}
712
713static void
714test_atexit (void)
715{
716 if (g_test_subprocess ())
717 {
718 g_atexit (func: atexit_func);
719 return;
720 }
721 g_test_trap_subprocess (NULL, usec_timeout: 0, test_flags: 0);
722 g_test_trap_assert_passed ();
723 g_test_trap_assert_stdout ("*atexit called*");
724}
725
726static void
727test_check_setuid (void)
728{
729 gboolean res;
730
731 res = GLIB_PRIVATE_CALL(g_check_setuid) ();
732 g_assert (!res);
733}
734
735/* Test the defined integer limits are correct, as some compilers have had
736 * problems with signed/unsigned conversion in the past. These limits should not
737 * vary between platforms, compilers or architectures.
738 *
739 * Use string comparisons to avoid the same systematic problems with unary minus
740 * application in C++. See https://gitlab.gnome.org/GNOME/glib/issues/1663. */
741static void
742test_int_limits (void)
743{
744 gchar *str = NULL;
745
746 g_test_bug (bug_uri_snippet: "https://gitlab.gnome.org/GNOME/glib/issues/1663");
747
748 str = g_strdup_printf (format: "%d %d %u\n"
749 "%" G_GINT16_FORMAT " %" G_GINT16_FORMAT " %" G_GUINT16_FORMAT "\n"
750 "%" G_GINT32_FORMAT " %" G_GINT32_FORMAT " %" G_GUINT32_FORMAT "\n"
751 "%" G_GINT64_FORMAT " %" G_GINT64_FORMAT " %" G_GUINT64_FORMAT "\n",
752 G_MININT8, G_MAXINT8, G_MAXUINT8,
753 G_MININT16, G_MAXINT16, G_MAXUINT16,
754 G_MININT32, G_MAXINT32, G_MAXUINT32,
755 G_MININT64, G_MAXINT64, G_MAXUINT64);
756
757 g_assert_cmpstr (str, ==,
758 "-128 127 255\n"
759 "-32768 32767 65535\n"
760 "-2147483648 2147483647 4294967295\n"
761 "-9223372036854775808 9223372036854775807 18446744073709551615\n");
762 g_free (mem: str);
763}
764
765static void
766test_clear_list (void)
767{
768 GList *list = NULL;
769
770 g_clear_list (&list, NULL);
771 g_assert_null (list);
772
773 list = g_list_prepend (list, data: "test");
774 g_assert_nonnull (list);
775
776 g_clear_list (&list, NULL);
777 g_assert_null (list);
778
779 g_clear_list (&list, g_free);
780 g_assert_null (list);
781
782 list = g_list_prepend (list, data: g_malloc (n_bytes: 16));
783 g_assert_nonnull (list);
784
785 g_clear_list (&list, g_free);
786 g_assert_null (list);
787}
788
789static void
790test_clear_slist (void)
791{
792 GSList *slist = NULL;
793
794 g_clear_slist (&slist, NULL);
795 g_assert_null (slist);
796
797 slist = g_slist_prepend (list: slist, data: "test");
798 g_assert_nonnull (slist);
799
800 g_clear_slist (&slist, NULL);
801 g_assert_null (slist);
802
803 g_clear_slist (&slist, g_free);
804 g_assert_null (slist);
805
806 slist = g_slist_prepend (list: slist, data: g_malloc (n_bytes: 16));
807 g_assert_nonnull (slist);
808
809 g_clear_slist (&slist, g_free);
810 g_assert_null (slist);
811}
812
813int
814main (int argc,
815 char *argv[])
816{
817 argv0 = argv[0];
818
819 /* for tmpdir test, need to do this early before g_get_any_init */
820 g_setenv (variable: "TMPDIR", value: "", TRUE);
821 g_unsetenv (variable: "TMP");
822 g_unsetenv (variable: "TEMP");
823
824 /* g_test_init() only calls g_set_prgname() if g_get_prgname()
825 * returns %NULL, but g_get_prgname() on Windows never returns NULL.
826 * So we need to do this by hand to make test_appname() work on
827 * Windows.
828 */
829 g_set_prgname (prgname: argv[0]);
830
831 g_test_init (argc: &argc, argv: &argv, NULL);
832 g_test_bug_base (uri_pattern: "http://bugzilla.gnome.org/");
833
834 g_test_add_func (testpath: "/utils/language-names", test_func: test_language_names);
835 g_test_add_func (testpath: "/utils/locale-variants", test_func: test_locale_variants);
836 g_test_add_func (testpath: "/utils/version", test_func: test_version);
837 g_test_add_func (testpath: "/utils/appname", test_func: test_appname);
838 g_test_add_func (testpath: "/utils/tmpdir", test_func: test_tmpdir);
839 g_test_add_func (testpath: "/utils/bits", test_func: test_bits);
840 g_test_add_func (testpath: "/utils/swap", test_func: test_swap);
841 g_test_add_func (testpath: "/utils/find-program", test_func: test_find_program);
842 g_test_add_func (testpath: "/utils/debug", test_func: test_debug);
843 g_test_add_func (testpath: "/utils/codeset", test_func: test_codeset);
844 g_test_add_func (testpath: "/utils/codeset2", test_func: test_codeset2);
845 g_test_add_func (testpath: "/utils/console-charset", test_func: test_console_charset);
846 g_test_add_func (testpath: "/utils/basename", test_func: test_basename);
847 g_test_add_func (testpath: "/utils/gettext", test_func: test_gettext);
848 g_test_add_func (testpath: "/utils/username", test_func: test_username);
849 g_test_add_func (testpath: "/utils/realname", test_func: test_realname);
850 g_test_add_func (testpath: "/utils/hostname", test_func: test_hostname);
851#ifdef G_OS_UNIX
852 g_test_add_func (testpath: "/utils/xdgdirs", test_func: test_xdg_dirs);
853#endif
854 g_test_add_func (testpath: "/utils/specialdir", test_func: test_special_dir);
855 g_test_add_func (testpath: "/utils/specialdir/desktop", test_func: test_desktop_special_dir);
856 g_test_add_func (testpath: "/utils/os-info", test_func: test_os_info);
857 g_test_add_func (testpath: "/utils/clear-pointer", test_func: test_clear_pointer);
858 g_test_add_func (testpath: "/utils/clear-pointer-cast", test_func: test_clear_pointer_cast);
859 g_test_add_func (testpath: "/utils/clear-pointer/side-effects", test_func: test_clear_pointer_side_effects);
860 g_test_add_func (testpath: "/utils/take-pointer", test_func: test_take_pointer);
861 g_test_add_func (testpath: "/utils/clear-source", test_func: test_clear_source);
862 g_test_add_func (testpath: "/utils/misc-mem", test_func: test_misc_mem);
863 g_test_add_func (testpath: "/utils/nullify", test_func: test_nullify);
864 g_test_add_func (testpath: "/utils/atexit", test_func: test_atexit);
865 g_test_add_func (testpath: "/utils/check-setuid", test_func: test_check_setuid);
866 g_test_add_func (testpath: "/utils/int-limits", test_func: test_int_limits);
867 g_test_add_func (testpath: "/utils/clear-list", test_func: test_clear_list);
868 g_test_add_func (testpath: "/utils/clear-slist", test_func: test_clear_slist);
869
870 return g_test_run ();
871}
872

source code of gtk/subprojects/glib/glib/tests/utils.c