Branch data Line data Source code
1 : : /* Unit tests for utilities
2 : : * Copyright (C) 2010 Red Hat, Inc.
3 : : *
4 : : * SPDX-License-Identifier: LicenseRef-old-glib-tests
5 : : *
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.
9 : : *
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.
13 : : *
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.
22 : : *
23 : : * Author: Matthias Clasen
24 : : */
25 : :
26 : : #ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
27 : : #define GLIB_DISABLE_DEPRECATION_WARNINGS
28 : : #endif
29 : :
30 : : #include "glib.h"
31 : : #include "glib-private.h"
32 : : #include "gutilsprivate.h"
33 : : #include "glib/gstdio.h"
34 : :
35 : : #include <stdlib.h>
36 : : #include <string.h>
37 : : #include <stdarg.h>
38 : : #ifdef G_OS_UNIX
39 : : #include <sys/utsname.h>
40 : : #endif
41 : : #ifdef G_OS_WIN32
42 : : #include <windows.h>
43 : : #endif
44 : :
45 : : static gboolean
46 : 20 : strv_check (const gchar * const *strv, ...)
47 : : {
48 : : va_list args;
49 : : gchar *s;
50 : : gint i;
51 : :
52 : 20 : va_start (args, strv);
53 [ + + ]: 115 : for (i = 0; strv[i]; i++)
54 : : {
55 : 95 : s = va_arg (args, gchar*);
56 [ - + ]: 95 : if (g_strcmp0 (strv[i], s) != 0)
57 : : {
58 : 0 : va_end (args);
59 : 0 : return FALSE;
60 : : }
61 : : }
62 : :
63 : 20 : va_end (args);
64 : :
65 : 20 : return TRUE;
66 : : }
67 : :
68 : : static void
69 : 5 : test_language_names (void)
70 : : {
71 : : const gchar * const *names;
72 : :
73 : 5 : g_setenv ("LANGUAGE", "de:en_US", TRUE);
74 : 5 : names = g_get_language_names ();
75 : 5 : g_assert (strv_check (names, "de", "en_US", "en", "C", NULL));
76 : :
77 : 5 : g_setenv ("LANGUAGE", "tt_RU.UTF-8@iqtelif", TRUE);
78 : 5 : names = g_get_language_names ();
79 : 5 : g_assert (strv_check (names,
80 : : "tt_RU.UTF-8@iqtelif",
81 : : "tt_RU@iqtelif",
82 : : "tt.UTF-8@iqtelif",
83 : : "tt@iqtelif",
84 : : "tt_RU.UTF-8",
85 : : "tt_RU",
86 : : "tt.UTF-8",
87 : : "tt",
88 : : "C",
89 : : NULL));
90 : 5 : }
91 : :
92 : : static void
93 : 5 : test_locale_variants (void)
94 : : {
95 : : char **v;
96 : :
97 : 5 : v = g_get_locale_variants ("fr_BE");
98 : 5 : g_assert (strv_check ((const gchar * const *) v, "fr_BE", "fr", NULL));
99 : 5 : g_strfreev (v);
100 : :
101 : 5 : v = g_get_locale_variants ("sr_SR@latin");
102 : 5 : g_assert (strv_check ((const gchar * const *) v, "sr_SR@latin", "sr@latin", "sr_SR", "sr", NULL));
103 : 5 : g_strfreev (v);
104 : 5 : }
105 : :
106 : : static void
107 : 5 : test_version (void)
108 : : {
109 [ - + ]: 5 : if (g_test_verbose ())
110 : 0 : 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);
113 : :
114 : 5 : g_assert (glib_check_version (GLIB_MAJOR_VERSION,
115 : : GLIB_MINOR_VERSION,
116 : : GLIB_MICRO_VERSION) == NULL);
117 : 5 : g_assert (glib_check_version (GLIB_MAJOR_VERSION,
118 : : GLIB_MINOR_VERSION,
119 : : 0) == NULL);
120 : 5 : g_assert (glib_check_version (GLIB_MAJOR_VERSION - 1,
121 : : 0,
122 : : 0) != NULL);
123 : 5 : g_assert (glib_check_version (GLIB_MAJOR_VERSION + 1,
124 : : 0,
125 : : 0) != NULL);
126 : 5 : g_assert (glib_check_version (GLIB_MAJOR_VERSION,
127 : : GLIB_MINOR_VERSION + 1,
128 : : 0) != NULL);
129 : : /* don't use + 1 here, since a +/-1 difference can
130 : : * happen due to post-release version bumps in git
131 : : */
132 : 5 : g_assert (glib_check_version (GLIB_MAJOR_VERSION,
133 : : GLIB_MINOR_VERSION,
134 : : GLIB_MICRO_VERSION + 3) != NULL);
135 : 5 : }
136 : :
137 : : static const gchar *argv0;
138 : :
139 : : static void
140 : 5 : test_appname (void)
141 : : {
142 : : const gchar *prgname;
143 : : const gchar *appname;
144 : :
145 : 5 : prgname = g_get_prgname ();
146 : 5 : appname = g_get_application_name ();
147 : 5 : g_assert_cmpstr (prgname, ==, argv0);
148 : 5 : g_assert_cmpstr (appname, ==, prgname);
149 : :
150 : 5 : g_set_prgname ("prgname");
151 : :
152 : 5 : prgname = g_get_prgname ();
153 : 5 : appname = g_get_application_name ();
154 : 5 : g_assert_cmpstr (prgname, ==, "prgname");
155 : 5 : g_assert_cmpstr (appname, ==, "prgname");
156 : :
157 : 5 : g_set_application_name ("appname");
158 : :
159 : 5 : prgname = g_get_prgname ();
160 : 5 : appname = g_get_application_name ();
161 : 5 : g_assert_cmpstr (prgname, ==, "prgname");
162 : 5 : g_assert_cmpstr (appname, ==, "appname");
163 : 5 : }
164 : :
165 : : static gpointer
166 : 20 : thread_prgname_check (gpointer data)
167 : : {
168 : 20 : gint *n_threads_got_prgname = (gint *) data;
169 : : const gchar *old_prgname;
170 : :
171 : 20 : old_prgname = g_get_prgname ();
172 : 20 : g_assert_cmpstr (old_prgname, ==, "prgname");
173 : :
174 : 20 : g_atomic_int_inc (n_threads_got_prgname);
175 : :
176 [ + + ]: 327732 : while (g_strcmp0 (g_get_prgname (), "prgname2") != 0);
177 : :
178 : 20 : return NULL;
179 : : }
180 : :
181 : : static void
182 : 5 : test_prgname_thread_safety (void)
183 : : {
184 : : gsize i;
185 : : gint n_threads_got_prgname;
186 : : GThread *threads[4];
187 : :
188 : 5 : g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/847");
189 : 5 : g_test_summary ("Test that threads racing to get and set the program name "
190 : : "always receive a valid program name.");
191 : :
192 : 5 : g_set_prgname ("prgname");
193 : 5 : g_atomic_int_set (&n_threads_got_prgname, 0);
194 : :
195 [ + + ]: 25 : for (i = 0; i < G_N_ELEMENTS (threads); i++)
196 : 20 : threads[i] = g_thread_new (NULL, thread_prgname_check, &n_threads_got_prgname);
197 : :
198 [ + + ]: 137 : while (g_atomic_int_get (&n_threads_got_prgname) != G_N_ELEMENTS (threads))
199 : 132 : g_usleep (50);
200 : :
201 : 5 : g_set_prgname ("prgname2");
202 : :
203 : : /* Wait for all the workers to exit. */
204 [ + + ]: 25 : for (i = 0; i < G_N_ELEMENTS (threads); i++)
205 : 20 : g_thread_join (threads[i]);
206 : :
207 : : /* reset prgname */
208 : 5 : g_set_prgname ("prgname");
209 : 5 : }
210 : :
211 : : static void
212 : 10 : test_tmpdir (void)
213 : : {
214 : 10 : char **envp = NULL;
215 : :
216 : 10 : g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=627969");
217 : 10 : g_test_summary ("Test that g_get_tmp_dir() returns a correct default if TMPDIR is set to the empty string");
218 : :
219 [ + + ]: 10 : if (g_test_subprocess ())
220 : : {
221 : 5 : g_assert_cmpstr (g_get_tmp_dir (), !=, "");
222 : 5 : return;
223 : : }
224 : :
225 : 5 : envp = g_get_environ ();
226 : :
227 : 5 : envp = g_environ_setenv (g_steal_pointer (&envp), "TMPDIR", "", TRUE);
228 : 5 : envp = g_environ_unsetenv (g_steal_pointer (&envp), "TMP");
229 : 5 : envp = g_environ_unsetenv (g_steal_pointer (&envp), "TEMP");
230 : :
231 : 5 : g_test_trap_subprocess_with_envp (NULL, (const gchar * const *) envp,
232 : : 0, G_TEST_SUBPROCESS_DEFAULT);
233 : 5 : g_test_trap_assert_passed ();
234 : 5 : g_strfreev (envp);
235 : : }
236 : :
237 : : #if defined(__GNUC__) && (__GNUC__ >= 4)
238 : : #define TEST_BUILTINS 1
239 : : #else
240 : : #define TEST_BUILTINS 0
241 : : #endif
242 : :
243 : : #if TEST_BUILTINS
244 : : static gint
245 : 1050000 : builtin_bit_nth_lsf1 (gulong mask, gint nth_bit)
246 : : {
247 [ + + ]: 1050000 : if (nth_bit >= 0)
248 : : {
249 [ + + ]: 1005000 : if (G_LIKELY (nth_bit < GLIB_SIZEOF_LONG * 8 - 1))
250 : 945000 : mask &= -(1UL << (nth_bit + 1));
251 : : else
252 : 60000 : mask = 0;
253 : : }
254 : 1050000 : return __builtin_ffsl (mask) - 1;
255 : : }
256 : :
257 : : static gint
258 : 1050000 : builtin_bit_nth_lsf2 (gulong mask, gint nth_bit)
259 : : {
260 [ + + ]: 1050000 : if (nth_bit >= 0)
261 : : {
262 [ + + ]: 1005000 : if (G_LIKELY (nth_bit < GLIB_SIZEOF_LONG * 8 - 1))
263 : 945000 : mask &= -(1UL << (nth_bit + 1));
264 : : else
265 : 60000 : mask = 0;
266 : : }
267 [ + + ]: 1050000 : return mask ? __builtin_ctzl (mask) : -1;
268 : : }
269 : :
270 : : static gint
271 : 1050000 : builtin_bit_nth_msf (gulong mask, gint nth_bit)
272 : : {
273 [ + + + + ]: 1050000 : if (nth_bit >= 0 && nth_bit < GLIB_SIZEOF_LONG * 8)
274 : 960000 : mask &= (1UL << nth_bit) - 1;
275 [ + + ]: 1050000 : return mask ? GLIB_SIZEOF_LONG * 8 - 1 - __builtin_clzl (mask) : -1;
276 : : }
277 : :
278 : : static guint
279 : 15000 : builtin_bit_storage (gulong number)
280 : : {
281 [ + + ]: 15000 : return number ? GLIB_SIZEOF_LONG * 8 - __builtin_clzl (number) : 1;
282 : : }
283 : : #endif
284 : :
285 : : static gint
286 : 1050000 : naive_bit_nth_lsf (gulong mask, gint nth_bit)
287 : : {
288 [ + + ]: 1050000 : if (G_UNLIKELY (nth_bit < -1))
289 : 30000 : nth_bit = -1;
290 [ + + ]: 12502260 : while (nth_bit < ((GLIB_SIZEOF_LONG * 8) - 1))
291 : : {
292 : 12034515 : nth_bit++;
293 [ + + ]: 12034515 : if (mask & (1UL << nth_bit))
294 : 582255 : return nth_bit;
295 : : }
296 : 467745 : return -1;
297 : : }
298 : :
299 : : static gint
300 : 1050000 : naive_bit_nth_msf (gulong mask, gint nth_bit)
301 : : {
302 [ + + + + ]: 1050000 : if (nth_bit < 0 || G_UNLIKELY (nth_bit > GLIB_SIZEOF_LONG * 8))
303 : 75000 : nth_bit = GLIB_SIZEOF_LONG * 8;
304 [ + + ]: 14510455 : while (nth_bit > 0)
305 : : {
306 : 14480190 : nth_bit--;
307 [ + + ]: 14480190 : if (mask & (1UL << nth_bit))
308 : 1019735 : return nth_bit;
309 : : }
310 : 30265 : return -1;
311 : : }
312 : :
313 : : static guint
314 : 15000 : naive_bit_storage (gulong number)
315 : : {
316 : 15000 : guint n_bits = 0;
317 : :
318 : : do
319 : : {
320 : 552270 : n_bits++;
321 : 552270 : number >>= 1;
322 : : }
323 [ + + ]: 552270 : while (number);
324 : 15000 : return n_bits;
325 : : }
326 : :
327 : : static void
328 : 5 : test_basic_bits (void)
329 : : {
330 : : gulong i;
331 : : gint nth_bit;
332 : :
333 : : /* we loop like this: 0, -1, 1, -2, 2, -3, 3, ... */
334 [ + + ]: 15005 : for (i = 0; (glong) i < 1500; i = -(i + ((glong) i >= 0)))
335 : : {
336 : 15000 : guint naive_bit_storage_i = naive_bit_storage (i);
337 : :
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.
341 : : *
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). */
345 : : #if TEST_BUILTINS
346 : 15000 : g_assert_cmpint (naive_bit_storage_i, ==, builtin_bit_storage (i));
347 : : #endif
348 : 15000 : g_assert_cmpint (naive_bit_storage_i, ==, g_bit_storage (i));
349 : 15000 : g_assert_cmpint (naive_bit_storage_i, ==, (g_bit_storage) (i));
350 : :
351 [ + + ]: 1065000 : for (nth_bit = -3; nth_bit <= 2 + GLIB_SIZEOF_LONG * 8; nth_bit++)
352 : : {
353 : 1050000 : gint naive_bit_nth_lsf_i_nth_bit = naive_bit_nth_lsf (i, nth_bit);
354 : 1050000 : gint naive_bit_nth_msf_i_nth_bit = naive_bit_nth_msf (i, nth_bit);
355 : :
356 : : #if TEST_BUILTINS
357 : 1050000 : g_assert_cmpint (naive_bit_nth_lsf_i_nth_bit, ==,
358 : : builtin_bit_nth_lsf1 (i, nth_bit));
359 : 1050000 : g_assert_cmpint (naive_bit_nth_lsf_i_nth_bit, ==,
360 : : builtin_bit_nth_lsf2 (i, nth_bit));
361 : : #endif
362 : 1050000 : g_assert_cmpint (naive_bit_nth_lsf_i_nth_bit, ==,
363 : : g_bit_nth_lsf (i, nth_bit));
364 : 1050000 : g_assert_cmpint (naive_bit_nth_lsf_i_nth_bit, ==,
365 : : (g_bit_nth_lsf) (i, nth_bit));
366 : :
367 : : #if TEST_BUILTINS
368 : 1050000 : g_assert_cmpint (naive_bit_nth_msf_i_nth_bit, ==,
369 : : builtin_bit_nth_msf (i, nth_bit));
370 : : #endif
371 : 1050000 : g_assert_cmpint (naive_bit_nth_msf_i_nth_bit, ==,
372 : : g_bit_nth_msf (i, nth_bit));
373 : 1050000 : g_assert_cmpint (naive_bit_nth_msf_i_nth_bit, ==,
374 : : (g_bit_nth_msf) (i, nth_bit));
375 : : }
376 : : }
377 : 5 : }
378 : :
379 : : static void
380 : 5 : test_bits (void)
381 : : {
382 : : gulong mask;
383 : : gint max_bit;
384 : : gint i, pos;
385 : :
386 : 5 : pos = g_bit_nth_lsf (0, -1);
387 : 5 : g_assert_cmpint (pos, ==, -1);
388 : :
389 : 5 : max_bit = sizeof (gulong) * 8;
390 [ + + ]: 325 : for (i = 0; i < max_bit; i++)
391 : : {
392 : 320 : mask = 1UL << i;
393 : :
394 : 320 : pos = g_bit_nth_lsf (mask, -1);
395 : 320 : g_assert_cmpint (pos, ==, i);
396 : :
397 : 320 : pos = g_bit_nth_lsf (mask, i - 3);
398 : 320 : g_assert_cmpint (pos , ==, i);
399 : :
400 : 320 : pos = g_bit_nth_lsf (mask, i);
401 : 320 : g_assert_cmpint (pos , ==, -1);
402 : :
403 : 320 : pos = g_bit_nth_lsf (mask, i + 1);
404 : 320 : g_assert_cmpint (pos , ==, -1);
405 : : }
406 : :
407 : 5 : pos = g_bit_nth_msf (0, -1);
408 : 5 : g_assert_cmpint (pos, ==, -1);
409 : :
410 [ + + ]: 325 : for (i = 0; i < max_bit; i++)
411 : : {
412 : 320 : mask = 1UL << i;
413 : :
414 : 320 : pos = g_bit_nth_msf (mask, -1);
415 : 320 : g_assert_cmpint (pos, ==, i);
416 : :
417 : 320 : pos = g_bit_nth_msf (mask, i + 3);
418 : 320 : g_assert_cmpint (pos , ==, i);
419 : :
420 : 320 : pos = g_bit_nth_msf (mask, i);
421 : 320 : g_assert_cmpint (pos , ==, -1);
422 : :
423 [ + + ]: 320 : if (i > 0)
424 : : {
425 : 315 : pos = g_bit_nth_msf (mask, i - 1);
426 : 315 : g_assert_cmpint (pos , ==, -1);
427 : : }
428 : : }
429 : 5 : }
430 : :
431 : : static void
432 : 5 : test_swap (void)
433 : : {
434 : : guint16 a16, b16;
435 : : guint32 a32, b32;
436 : : guint64 a64, b64;
437 : :
438 : 5 : a16 = 0xaabb;
439 : 5 : b16 = 0xbbaa;
440 : :
441 : 5 : g_assert_cmpint (GUINT16_SWAP_LE_BE (a16), ==, b16);
442 : :
443 : 5 : a32 = 0xaaaabbbb;
444 : 5 : b32 = 0xbbbbaaaa;
445 : :
446 : 5 : g_assert_cmpint (GUINT32_SWAP_LE_BE (a32), ==, b32);
447 : :
448 : 5 : a64 = G_GUINT64_CONSTANT(0xaaaaaaaabbbbbbbb);
449 : 5 : b64 = G_GUINT64_CONSTANT(0xbbbbbbbbaaaaaaaa);
450 : :
451 : 5 : g_assert_cmpint (GUINT64_SWAP_LE_BE (a64), ==, b64);
452 : 5 : }
453 : :
454 : : static void
455 : 5 : test_find_program (void)
456 : : {
457 : : gchar *res;
458 : :
459 : : #ifdef G_OS_UNIX
460 : : gchar *relative_path;
461 : : gchar *absolute_path;
462 : : gchar *cwd;
463 : : gsize i;
464 : :
465 : 5 : res = g_find_program_in_path ("sh");
466 : 5 : g_assert (res != NULL);
467 : 5 : g_free (res);
468 : :
469 : 5 : res = g_find_program_in_path ("/bin/sh");
470 : 5 : g_assert (res != NULL);
471 : 5 : g_free (res);
472 : :
473 : : /* Resolve any symlinks in the CWD as that breaks the test e.g.
474 : : * with the FreeBSD /home/ -> /usr/home symlink. */
475 : 5 : cwd = realpath (".", NULL);
476 : 5 : absolute_path = g_find_program_in_path ("sh");
477 : 5 : relative_path = g_strdup (absolute_path);
478 [ + + ]: 130 : for (i = 0; cwd[i] != '\0'; i++)
479 : : {
480 [ + + + - ]: 125 : if (cwd[i] == '/' && cwd[i + 1] != '\0')
481 : : {
482 : 20 : gchar *relative_path_2 = g_strconcat ("../", relative_path, NULL);
483 : 20 : g_free (relative_path);
484 : 20 : relative_path = relative_path_2;
485 : : }
486 : : }
487 : 5 : res = g_find_program_in_path (relative_path);
488 : 5 : g_assert_nonnull (res);
489 : 5 : g_assert_true (g_path_is_absolute (res));
490 : 5 : g_free (cwd);
491 : 5 : g_free (absolute_path);
492 : 5 : g_free (relative_path);
493 : 5 : g_free (res);
494 : :
495 : : #else
496 : : /* There's not a lot we can search for that would reliably work both
497 : : * on real Windows and mingw.
498 : : */
499 : : #endif
500 : :
501 : 5 : res = g_find_program_in_path ("this_program_does_not_exit");
502 : 5 : g_assert (res == NULL);
503 : :
504 : 5 : res = g_find_program_in_path ("/bin");
505 : 5 : g_assert (res == NULL);
506 : :
507 : 5 : res = g_find_program_in_path ("/etc/passwd");
508 : 5 : g_assert (res == NULL);
509 : 5 : }
510 : :
511 : : static char *
512 : 65 : find_program_for_path (const char *program,
513 : : const char *path,
514 : : const char *working_dir)
515 : : {
516 : 65 : return GLIB_PRIVATE_CALL(g_find_program_for_path) (program, path, working_dir);
517 : : }
518 : :
519 : : static void
520 : 5 : test_find_program_for_path (void)
521 : : {
522 : 5 : GError *error = NULL;
523 : : /* Using .cmd extension to make windows to consider it an executable */
524 : 5 : const char *command_to_find = "just-an-exe-file.cmd";
525 : : char *path;
526 : : char *exe_path;
527 : : char *found_path;
528 : : char *old_cwd;
529 : : char *tmp;
530 : :
531 : 5 : tmp = g_dir_make_tmp ("find_program_for_path_XXXXXXX", &error);
532 : 5 : g_assert_no_error (error);
533 : :
534 : 5 : path = g_build_filename (tmp, "sub-path", NULL);
535 : 5 : g_mkdir (path, 0700);
536 : 5 : g_assert_true (g_file_test (path, G_FILE_TEST_IS_DIR));
537 : :
538 : 5 : exe_path = g_build_filename (path, command_to_find, NULL);
539 : 5 : g_file_set_contents (exe_path, "", -1, &error);
540 : 5 : g_assert_no_error (error);
541 : 5 : g_assert_true (g_file_test (exe_path, G_FILE_TEST_EXISTS));
542 : :
543 : : #ifdef G_OS_UNIX
544 : 5 : g_assert_no_errno (g_chmod (exe_path, 0500));
545 : : #endif
546 : 5 : g_assert_true (g_file_test (exe_path, G_FILE_TEST_IS_EXECUTABLE));
547 : :
548 : 5 : g_assert_null (g_find_program_in_path (command_to_find));
549 : 5 : g_assert_null (find_program_for_path (command_to_find, NULL, NULL));
550 : :
551 : 5 : found_path = find_program_for_path (command_to_find, path, NULL);
552 : : #ifdef __APPLE__
553 : : g_assert_nonnull (found_path);
554 : : g_assert_true (g_str_has_suffix (found_path, exe_path));
555 : : #else
556 : 5 : g_assert_cmpstr (exe_path, ==, found_path);
557 : : #endif
558 : 5 : g_clear_pointer (&found_path, g_free);
559 : :
560 : 5 : found_path = find_program_for_path (command_to_find, path, path);
561 : : #ifdef __APPLE__
562 : : g_assert_nonnull (found_path);
563 : : g_assert_true (g_str_has_suffix (found_path, exe_path));
564 : : #else
565 : 5 : g_assert_cmpstr (exe_path, ==, found_path);
566 : : #endif
567 : 5 : g_clear_pointer (&found_path, g_free);
568 : :
569 : 5 : found_path = find_program_for_path (command_to_find, NULL, path);
570 : : #ifdef __APPLE__
571 : : g_assert_nonnull (found_path);
572 : : g_assert_true (g_str_has_suffix (found_path, exe_path));
573 : : #else
574 : 5 : g_assert_cmpstr (exe_path, ==, found_path);
575 : : #endif
576 : 5 : g_clear_pointer (&found_path, g_free);
577 : :
578 : 5 : found_path = find_program_for_path (command_to_find, "::", path);
579 : : #ifdef __APPLE__
580 : : g_assert_nonnull (found_path);
581 : : g_assert_true (g_str_has_suffix (found_path, exe_path));
582 : : #else
583 : 5 : g_assert_cmpstr (exe_path, ==, found_path);
584 : : #endif
585 : 5 : g_clear_pointer (&found_path, g_free);
586 : :
587 : 5 : old_cwd = g_get_current_dir ();
588 : 5 : g_chdir (path);
589 : 5 : found_path =
590 : 5 : find_program_for_path (command_to_find,
591 : : G_SEARCHPATH_SEPARATOR_S G_SEARCHPATH_SEPARATOR_S, NULL);
592 : 5 : g_chdir (old_cwd);
593 : 5 : g_clear_pointer (&old_cwd, g_free);
594 : : #ifdef __APPLE__
595 : : g_assert_nonnull (found_path);
596 : : g_assert_true (g_str_has_suffix (found_path, exe_path));
597 : : #else
598 : 5 : g_assert_cmpstr (exe_path, ==, found_path);
599 : : #endif
600 : 5 : g_clear_pointer (&found_path, g_free);
601 : :
602 : 5 : old_cwd = g_get_current_dir ();
603 : 5 : g_chdir (tmp);
604 : 5 : found_path =
605 : 5 : find_program_for_path (command_to_find,
606 : : G_SEARCHPATH_SEPARATOR_S G_SEARCHPATH_SEPARATOR_S, "sub-path");
607 : 5 : g_chdir (old_cwd);
608 : 5 : g_clear_pointer (&old_cwd, g_free);
609 : : #ifdef __APPLE__
610 : : g_assert_nonnull (found_path);
611 : : g_assert_true (g_str_has_suffix (found_path, exe_path));
612 : : #else
613 : 5 : g_assert_cmpstr (exe_path, ==, found_path);
614 : : #endif
615 : 5 : g_clear_pointer (&found_path, g_free);
616 : :
617 : 5 : g_assert_null (
618 : : find_program_for_path (command_to_find,
619 : : G_SEARCHPATH_SEPARATOR_S G_SEARCHPATH_SEPARATOR_S, "other-sub-path"));
620 : :
621 : 5 : found_path = find_program_for_path (command_to_find,
622 : : G_SEARCHPATH_SEPARATOR_S "sub-path" G_SEARCHPATH_SEPARATOR_S, tmp);
623 : : #ifdef __APPLE__
624 : : g_assert_nonnull (found_path);
625 : : g_assert_true (g_str_has_suffix (found_path, exe_path));
626 : : #else
627 : 5 : g_assert_cmpstr (exe_path, ==, found_path);
628 : : #endif
629 : 5 : g_clear_pointer (&found_path, g_free);
630 : :
631 : 5 : g_assert_null (find_program_for_path (command_to_find,
632 : : G_SEARCHPATH_SEPARATOR_S "other-sub-path" G_SEARCHPATH_SEPARATOR_S, tmp));
633 : :
634 : : #ifdef G_OS_UNIX
635 : 5 : found_path = find_program_for_path ("sh", NULL, tmp);
636 : 5 : g_assert_nonnull (found_path);
637 : 5 : g_clear_pointer (&found_path, g_free);
638 : :
639 : 5 : old_cwd = g_get_current_dir ();
640 : 5 : g_chdir ("/");
641 : 5 : found_path = find_program_for_path ("sh", "sbin:bin:usr/bin:usr/sbin", NULL);
642 : 5 : g_chdir (old_cwd);
643 : 5 : g_clear_pointer (&old_cwd, g_free);
644 : 5 : g_assert_nonnull (found_path);
645 : 5 : g_clear_pointer (&found_path, g_free);
646 : :
647 : 5 : found_path = find_program_for_path ("sh", "sbin:bin:usr/bin:usr/sbin", "/");
648 : 5 : g_assert_nonnull (found_path);
649 : 5 : g_clear_pointer (&found_path, g_free);
650 : : #endif /* G_OS_UNIX */
651 : :
652 : 5 : g_clear_pointer (&exe_path, g_free);
653 : 5 : g_clear_pointer (&path, g_free);
654 : 5 : g_clear_pointer (&tmp, g_free);
655 : 5 : g_clear_error (&error);
656 : 5 : }
657 : :
658 : : static void
659 : 10 : test_debug (void)
660 : : {
661 : 10 : GDebugKey keys[] = {
662 : : { "key1", 1 },
663 : : { "key2", 2 },
664 : : { "key3", 4 },
665 : : };
666 : : guint res;
667 : :
668 : 10 : res = g_parse_debug_string (NULL, keys, G_N_ELEMENTS (keys));
669 : 10 : g_assert_cmpint (res, ==, 0);
670 : :
671 : 10 : res = g_parse_debug_string ("foobabla;#!%!$%112 223", keys, G_N_ELEMENTS (keys));
672 : 10 : g_assert_cmpint (res, ==, 0);
673 : :
674 : 10 : res = g_parse_debug_string ("key1:key2", keys, G_N_ELEMENTS (keys));
675 : 10 : g_assert_cmpint (res, ==, 3);
676 : :
677 : 10 : res = g_parse_debug_string ("key1;key2", keys, G_N_ELEMENTS (keys));
678 : 10 : g_assert_cmpint (res, ==, 3);
679 : :
680 : 10 : res = g_parse_debug_string ("key1,key2", keys, G_N_ELEMENTS (keys));
681 : 10 : g_assert_cmpint (res, ==, 3);
682 : :
683 : 10 : res = g_parse_debug_string ("key1 key2", keys, G_N_ELEMENTS (keys));
684 : 10 : g_assert_cmpint (res, ==, 3);
685 : :
686 : 10 : res = g_parse_debug_string ("key1\tkey2", keys, G_N_ELEMENTS (keys));
687 : 10 : g_assert_cmpint (res, ==, 3);
688 : :
689 : 10 : res = g_parse_debug_string ("all", keys, G_N_ELEMENTS (keys));
690 : 10 : g_assert_cmpint (res, ==, 7);
691 : :
692 [ + + ]: 10 : if (g_test_subprocess ())
693 : : {
694 : 5 : res = g_parse_debug_string ("help", keys, G_N_ELEMENTS (keys));
695 : 5 : g_assert_cmpint (res, ==, 0);
696 : 5 : return;
697 : : }
698 : 5 : g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
699 : 5 : g_test_trap_assert_passed ();
700 : 5 : g_test_trap_assert_stderr ("*Supported debug values: key1 key2 key3 all help*");
701 : : }
702 : :
703 : : static void
704 : 5 : test_codeset (void)
705 : : {
706 : : gchar *c;
707 : : const gchar *c2;
708 : :
709 : 5 : c = g_get_codeset ();
710 : 5 : g_get_charset (&c2);
711 : :
712 : 5 : g_assert_cmpstr (c, ==, c2);
713 : :
714 : 5 : g_free (c);
715 : 5 : }
716 : :
717 : : static void
718 : 10 : test_codeset2 (void)
719 : : {
720 [ + + ]: 10 : if (g_test_subprocess ())
721 : : {
722 : : const gchar *c;
723 : 5 : g_setenv ("CHARSET", "UTF-8", TRUE);
724 : 5 : g_get_charset (&c);
725 : 5 : g_assert_cmpstr (c, ==, "UTF-8");
726 : 5 : return;
727 : : }
728 : 5 : g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
729 : 5 : g_test_trap_assert_passed ();
730 : : }
731 : :
732 : : static void
733 : 5 : test_console_charset (void)
734 : : {
735 : : const gchar *c1;
736 : : const gchar *c2;
737 : :
738 : : #ifdef G_OS_WIN32
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"));
742 : : g_unsetenv ("LANG");
743 : :
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");
748 : :
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");
753 : :
754 : : /* reset environment */
755 : : if (initial_cp)
756 : : SetConsoleOutputCP (initial_cp);
757 : : if (initial_lang)
758 : : g_setenv ("LANG", initial_lang, TRUE);
759 : : g_free (initial_lang);
760 : : #else
761 : 5 : g_get_charset (&c1);
762 : 5 : g_get_console_charset (&c2);
763 : :
764 : 5 : g_assert_cmpstr (c1, ==, c2);
765 : : #endif
766 : 5 : }
767 : :
768 : : extern const gchar *glib_pgettext (const gchar *msgidctxt, gsize msgidoffset);
769 : :
770 : : static void
771 : 5 : test_gettext (void)
772 : : {
773 : : const gchar *am0, *am1, *am2, *am3;
774 : :
775 : 5 : am0 = glib_pgettext ("GDateTime\004AM", strlen ("GDateTime") + 1);
776 : 5 : am1 = g_dpgettext ("glib20", "GDateTime\004AM", strlen ("GDateTime") + 1);
777 : 5 : am2 = g_dpgettext ("glib20", "GDateTime|AM", 0);
778 : 5 : am3 = g_dpgettext2 ("glib20", "GDateTime", "AM");
779 : :
780 : 5 : g_assert_cmpstr (am0, ==, am1);
781 : 5 : g_assert_cmpstr (am1, ==, am2);
782 : 5 : g_assert_cmpstr (am2, ==, am3);
783 : 5 : }
784 : :
785 : : static void
786 : 5 : test_username (void)
787 : : {
788 : : const gchar *name;
789 : :
790 : 5 : name = g_get_user_name ();
791 : :
792 : 5 : g_assert (name != NULL);
793 : 5 : }
794 : :
795 : : static void
796 : 5 : test_realname (void)
797 : : {
798 : : const gchar *name;
799 : :
800 : 5 : name = g_get_real_name ();
801 : :
802 : 5 : g_assert (name != NULL);
803 : 5 : }
804 : :
805 : : static void
806 : 5 : test_hostname (void)
807 : : {
808 : : const gchar *name;
809 : :
810 : 5 : name = g_get_host_name ();
811 : :
812 : 5 : g_assert (name != NULL);
813 : 5 : g_assert_true (g_utf8_validate (name, -1, NULL));
814 : 5 : }
815 : :
816 : : #ifdef G_OS_UNIX
817 : : static void
818 : 5 : test_xdg_dirs (void)
819 : : {
820 : : gchar *xdg;
821 : : const gchar *dir;
822 : : const gchar * const *dirs;
823 : : gchar *s;
824 : :
825 : 5 : xdg = g_strdup (g_getenv ("XDG_CONFIG_HOME"));
826 [ + - ]: 5 : if (!xdg)
827 : 5 : xdg = g_build_filename (g_get_home_dir (), ".config", NULL);
828 : :
829 : 5 : dir = g_get_user_config_dir ();
830 : :
831 : 5 : g_assert_cmpstr (dir, ==, xdg);
832 : 5 : g_free (xdg);
833 : :
834 : 5 : xdg = g_strdup (g_getenv ("XDG_DATA_HOME"));
835 [ + - ]: 5 : if (!xdg)
836 : 5 : xdg = g_build_filename (g_get_home_dir (), ".local", "share", NULL);
837 : :
838 : 5 : dir = g_get_user_data_dir ();
839 : :
840 : 5 : g_assert_cmpstr (dir, ==, xdg);
841 : 5 : g_free (xdg);
842 : :
843 : 5 : xdg = g_strdup (g_getenv ("XDG_CACHE_HOME"));
844 [ + - ]: 5 : if (!xdg)
845 : 5 : xdg = g_build_filename (g_get_home_dir (), ".cache", NULL);
846 : :
847 : 5 : dir = g_get_user_cache_dir ();
848 : :
849 : 5 : g_assert_cmpstr (dir, ==, xdg);
850 : 5 : g_free (xdg);
851 : :
852 : 5 : xdg = g_strdup (g_getenv ("XDG_STATE_HOME"));
853 [ + - ]: 5 : if (!xdg)
854 : 5 : xdg = g_build_filename (g_get_home_dir (), ".local/state", NULL);
855 : :
856 : 5 : dir = g_get_user_state_dir ();
857 : :
858 : 5 : g_assert_cmpstr (dir, ==, xdg);
859 : 5 : g_free (xdg);
860 : :
861 : 5 : xdg = g_strdup (g_getenv ("XDG_RUNTIME_DIR"));
862 [ + - ]: 5 : if (!xdg)
863 : 10 : xdg = g_strdup (g_get_user_cache_dir ());
864 : :
865 : 5 : dir = g_get_user_runtime_dir ();
866 : :
867 : 5 : g_assert_cmpstr (dir, ==, xdg);
868 : 5 : g_free (xdg);
869 : :
870 : 5 : xdg = (gchar *)g_getenv ("XDG_CONFIG_DIRS");
871 [ + - ]: 5 : if (!xdg)
872 : 5 : xdg = "/etc/xdg";
873 : :
874 : 5 : dirs = g_get_system_config_dirs ();
875 : :
876 : 5 : s = g_strjoinv (":", (gchar **)dirs);
877 : :
878 : 5 : g_assert_cmpstr (s, ==, xdg);
879 : :
880 : 5 : g_free (s);
881 : 5 : }
882 : : #endif
883 : :
884 : : static void
885 : 5 : test_special_dir (void)
886 : : {
887 : : const gchar *dir, *dir2;
888 : :
889 : 5 : dir = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
890 : 5 : g_reload_user_special_dirs_cache ();
891 : 5 : dir2 = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
892 : :
893 : 5 : g_assert_cmpstr (dir, ==, dir2);
894 : 5 : }
895 : :
896 : : static void
897 : 5 : test_desktop_special_dir (void)
898 : : {
899 : : const gchar *dir, *dir2;
900 : :
901 : 5 : dir = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
902 : 5 : g_assert (dir != NULL);
903 : :
904 : 5 : g_reload_user_special_dirs_cache ();
905 : 5 : dir2 = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
906 : 5 : g_assert (dir2 != NULL);
907 : 5 : }
908 : :
909 : : static void
910 : 5 : test_os_info (void)
911 : : {
912 : : gchar *name;
913 : 5 : gchar *contents = NULL;
914 : : #if defined (G_OS_UNIX) && !(defined (G_OS_WIN32) || defined (__APPLE__))
915 : : struct utsname info;
916 : : #endif
917 : :
918 : : /* Whether this is implemented or not, it must not crash */
919 : 5 : name = g_get_os_info (G_OS_INFO_KEY_NAME);
920 [ + - ]: 5 : g_test_message ("%s: %s",
921 : : G_OS_INFO_KEY_NAME,
922 : : name == NULL ? "(null)" : name);
923 : :
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 [ - + - - ]: 5 : if (g_file_get_contents ("/etc/os-release", &contents, NULL, NULL) ||
929 [ # # ]: 0 : g_file_get_contents ("/usr/lib/os-release", &contents, NULL, NULL) ||
930 : 0 : uname (&info) == 0)
931 : 5 : g_assert_nonnull (name);
932 : : else
933 : 0 : g_test_skip ("os-release(5) API not implemented on this platform");
934 : : #else
935 : : g_test_skip ("g_get_os_info() not supported on this platform");
936 : : #endif
937 : :
938 : 5 : g_free (name);
939 : 5 : g_free (contents);
940 : 5 : }
941 : :
942 : : static void
943 : 0 : source_test (gpointer data)
944 : : {
945 : : g_assert_not_reached ();
946 : : }
947 : :
948 : : static void
949 : 5 : test_clear_source (void)
950 : : {
951 : : guint id;
952 : :
953 : 5 : id = g_idle_add_once (source_test, NULL);
954 : 5 : g_assert_cmpuint (id, >, 0);
955 : :
956 : 5 : g_clear_handle_id (&id, g_source_remove);
957 : 5 : g_assert_cmpuint (id, ==, 0);
958 : :
959 : 5 : id = g_timeout_add_once (100, source_test, NULL);
960 : 5 : g_assert_cmpuint (id, >, 0);
961 : :
962 : 5 : g_clear_handle_id (&id, g_source_remove);
963 : 5 : g_assert_cmpuint (id, ==, 0);
964 : 5 : }
965 : :
966 : : static void
967 : 5 : test_clear_pointer (void)
968 : : {
969 : : gpointer a;
970 : :
971 : 5 : a = g_malloc (5);
972 : 5 : g_clear_pointer (&a, g_free);
973 : 5 : g_assert (a == NULL);
974 : :
975 : 5 : a = g_malloc (5);
976 : 5 : (g_clear_pointer) (&a, g_free);
977 : 5 : g_assert (a == NULL);
978 : 5 : }
979 : :
980 : : /* Test that g_clear_pointer() works with a GDestroyNotify which contains a cast.
981 : : * See https://gitlab.gnome.org/GNOME/glib/issues/1425 */
982 : : static void
983 : 5 : test_clear_pointer_cast (void)
984 : : {
985 : 5 : GHashTable *hash_table = NULL;
986 : :
987 : 5 : hash_table = g_hash_table_new (g_str_hash, g_str_equal);
988 : :
989 : 5 : g_assert_nonnull (hash_table);
990 : :
991 : 5 : g_clear_pointer (&hash_table, (void (*) (GHashTable *)) g_hash_table_destroy);
992 : :
993 : 5 : g_assert_null (hash_table);
994 : 5 : }
995 : :
996 : : /* Test that the macro version of g_clear_pointer() only evaluates its argument
997 : : * once, just like the function version would. */
998 : : static void
999 : 5 : test_clear_pointer_side_effects (void)
1000 : : {
1001 : : gchar **my_string_array, **i;
1002 : :
1003 : 5 : my_string_array = g_new0 (gchar*, 3);
1004 : 5 : my_string_array[0] = g_strdup ("hello");
1005 : 5 : my_string_array[1] = g_strdup ("there");
1006 : 5 : my_string_array[2] = NULL;
1007 : :
1008 : 5 : i = my_string_array;
1009 : :
1010 : 5 : g_clear_pointer (i++, g_free);
1011 : :
1012 : 5 : g_assert_true (i == &my_string_array[1]);
1013 : 5 : g_assert_null (my_string_array[0]);
1014 : 5 : g_assert_nonnull (my_string_array[1]);
1015 : 5 : g_assert_null (my_string_array[2]);
1016 : :
1017 : 5 : g_free (my_string_array[1]);
1018 : 5 : g_free (my_string_array[2]);
1019 : 5 : g_free (my_string_array);
1020 : 5 : }
1021 : :
1022 : : static int obj_count;
1023 : :
1024 : : static void
1025 : 10 : get_obj (gpointer *obj_out)
1026 : : {
1027 : 10 : gpointer obj = g_malloc (5);
1028 : 10 : obj_count++;
1029 : :
1030 [ + + ]: 10 : if (obj_out)
1031 : 5 : *obj_out = g_steal_pointer (&obj);
1032 : :
1033 [ + + ]: 10 : if (obj)
1034 : : {
1035 : 5 : g_free (obj);
1036 : 5 : obj_count--;
1037 : : }
1038 : 10 : }
1039 : :
1040 : : static void
1041 : 5 : test_take_pointer (void)
1042 : : {
1043 : : gpointer a;
1044 : : gpointer b;
1045 : :
1046 : 5 : get_obj (NULL);
1047 : :
1048 : 5 : get_obj (&a);
1049 : 5 : g_assert (a);
1050 : :
1051 : : /* ensure that it works to skip the macro */
1052 : 5 : b = (g_steal_pointer) (&a);
1053 : 5 : g_assert (!a);
1054 : 5 : obj_count--;
1055 : 5 : g_free (b);
1056 : :
1057 : 5 : g_assert (!obj_count);
1058 : 5 : }
1059 : :
1060 : : static void
1061 : 5 : test_misc_mem (void)
1062 : : {
1063 : : gpointer a;
1064 : :
1065 : 5 : a = g_try_malloc (0);
1066 : 5 : g_assert (a == NULL);
1067 : :
1068 : 5 : a = g_try_malloc0 (0);
1069 : 5 : g_assert (a == NULL);
1070 : :
1071 : 5 : a = g_malloc (16);
1072 : 5 : a = g_try_realloc (a, 20);
1073 : 5 : a = g_try_realloc (a, 0);
1074 : :
1075 : 5 : g_assert (a == NULL);
1076 : 5 : }
1077 : :
1078 : : static void
1079 : 0 : aligned_alloc_nz (void)
1080 : : {
1081 : : gpointer a;
1082 : :
1083 : : /* Test an alignment that’s zero */
1084 : 0 : a = g_aligned_alloc (16, sizeof(char), 0);
1085 : 0 : g_aligned_free (a);
1086 : 0 : exit (0);
1087 : : }
1088 : :
1089 : : static void
1090 : 0 : aligned_alloc_npot (void)
1091 : : {
1092 : : gpointer a;
1093 : :
1094 : : /* Test an alignment that’s not a power of two */
1095 : 0 : a = g_aligned_alloc (16, sizeof(char), 15);
1096 : 0 : g_aligned_free (a);
1097 : 0 : exit (0);
1098 : : }
1099 : :
1100 : : static void
1101 : 0 : aligned_alloc_nmov (void)
1102 : : {
1103 : : gpointer a;
1104 : :
1105 : : /* Test an alignment that’s not a multiple of sizeof(void*) */
1106 : 0 : a = g_aligned_alloc (16, sizeof(char), sizeof(void *) / 2);
1107 : 0 : g_aligned_free (a);
1108 : 0 : exit (0);
1109 : : }
1110 : :
1111 : : static void
1112 : 5 : test_aligned_mem (void)
1113 : : {
1114 : : gpointer a;
1115 : :
1116 : 5 : g_test_summary ("Aligned memory allocator");
1117 : :
1118 : 5 : a = g_aligned_alloc (0, sizeof (int), MAX (sizeof (void *), 8));
1119 : 5 : g_assert_null (a);
1120 : :
1121 : 5 : a = g_aligned_alloc0 (0, sizeof (int), MAX (sizeof (void *), 8));
1122 : 5 : g_assert_null (a);
1123 : :
1124 : 5 : a = g_aligned_alloc (16, 0, MAX (sizeof (void *), 8));
1125 : 5 : g_assert_null (a);
1126 : :
1127 : : #define CHECK_SUBPROCESS_FAIL(name,msg) do { \
1128 : : if (g_test_undefined ()) \
1129 : : { \
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 (); \
1134 : : } \
1135 : : } while (0)
1136 : :
1137 [ + - ]: 5 : CHECK_SUBPROCESS_FAIL (aligned_alloc_nz, "Alignment must not be zero");
1138 [ + - ]: 5 : CHECK_SUBPROCESS_FAIL (aligned_alloc_npot, "Alignment must be a power of two");
1139 [ + - ]: 5 : CHECK_SUBPROCESS_FAIL (aligned_alloc_nmov, "Alignment must be a multiple of sizeof(void*)");
1140 : 5 : }
1141 : :
1142 : : static void
1143 : 5 : test_aligned_mem_alignment (void)
1144 : : {
1145 : : gchar *p;
1146 : :
1147 : 5 : g_test_summary ("Check that g_aligned_alloc() returns a correctly aligned pointer");
1148 : :
1149 : 5 : p = g_aligned_alloc (5, sizeof (*p), 256);
1150 : 5 : g_assert_nonnull (p);
1151 : 5 : g_assert_cmpuint (((guintptr) p) % 256, ==, 0);
1152 : :
1153 : 5 : g_aligned_free (p);
1154 : 5 : }
1155 : :
1156 : : static void
1157 : 5 : test_aligned_mem_zeroed (void)
1158 : : {
1159 : 5 : gsize n_blocks = 10;
1160 : : guint *p;
1161 : : gsize i;
1162 : :
1163 : 5 : g_test_summary ("Check that g_aligned_alloc0() zeroes out its allocation");
1164 : :
1165 : 5 : p = g_aligned_alloc0 (n_blocks, sizeof (*p), 16);
1166 : 5 : g_assert_nonnull (p);
1167 : :
1168 [ + + ]: 55 : for (i = 0; i < n_blocks; i++)
1169 : 50 : g_assert_cmpuint (p[i], ==, 0);
1170 : :
1171 : 5 : g_aligned_free (p);
1172 : 5 : }
1173 : :
1174 : : static void
1175 : 5 : test_aligned_mem_free_sized (void)
1176 : : {
1177 : 5 : gsize n_blocks = 10;
1178 : : guint *p;
1179 : :
1180 : 5 : g_test_summary ("Check that g_aligned_free_sized() works");
1181 : :
1182 : 5 : p = g_aligned_alloc (n_blocks, sizeof (*p), 16);
1183 : 5 : g_assert_nonnull (p);
1184 : :
1185 : 5 : g_aligned_free_sized (p, sizeof (*p), n_blocks * 16);
1186 : :
1187 : : /* NULL should be ignored */
1188 : 5 : g_aligned_free_sized (NULL, sizeof (*p), n_blocks * 16);
1189 : 5 : }
1190 : :
1191 : : static void
1192 : 5 : test_free_sized (void)
1193 : : {
1194 : : gpointer p;
1195 : :
1196 : 5 : g_test_summary ("Check that g_free_sized() works");
1197 : :
1198 : 5 : p = g_malloc (123);
1199 : 5 : g_assert_nonnull (p);
1200 : :
1201 : 5 : g_free_sized (p, 123);
1202 : :
1203 : : /* NULL should be ignored */
1204 : 5 : g_free_sized (NULL, 123);
1205 : 5 : }
1206 : :
1207 : : static void
1208 : 5 : test_nullify (void)
1209 : : {
1210 : 5 : gpointer p = &test_nullify;
1211 : :
1212 : 5 : g_assert (p != NULL);
1213 : :
1214 : 5 : g_nullify_pointer (&p);
1215 : :
1216 : 5 : g_assert (p == NULL);
1217 : 5 : }
1218 : :
1219 : : static void
1220 : 5 : atexit_func (void)
1221 : : {
1222 : 5 : g_print ("atexit called");
1223 : 5 : }
1224 : :
1225 : : static void
1226 : 10 : test_atexit (void)
1227 : : {
1228 [ + + ]: 10 : if (g_test_subprocess ())
1229 : : {
1230 : 5 : g_atexit (atexit_func);
1231 : 5 : return;
1232 : : }
1233 : 5 : g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
1234 : 5 : g_test_trap_assert_passed ();
1235 : 5 : g_test_trap_assert_stdout ("*atexit called*");
1236 : : }
1237 : :
1238 : : static void
1239 : 5 : test_check_setuid (void)
1240 : : {
1241 : : gboolean res;
1242 : :
1243 : 5 : res = GLIB_PRIVATE_CALL(g_check_setuid) ();
1244 : 5 : g_assert (!res);
1245 : 5 : }
1246 : :
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.
1250 : : *
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. */
1253 : : static void
1254 : 5 : test_int_limits (void)
1255 : : {
1256 : 5 : gchar *str = NULL;
1257 : :
1258 : 5 : g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1663");
1259 : :
1260 : 5 : 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);
1268 : :
1269 : 5 : g_assert_cmpstr (str, ==,
1270 : : "-128 127 255\n"
1271 : : "-32768 32767 65535\n"
1272 : : "-2147483648 2147483647 4294967295\n"
1273 : : "-9223372036854775808 9223372036854775807 18446744073709551615\n");
1274 : 5 : g_free (str);
1275 : 5 : }
1276 : :
1277 : : static void
1278 : 5 : test_clear_list (void)
1279 : : {
1280 : 5 : GList *list = NULL;
1281 : :
1282 : 5 : g_clear_list (&list, NULL);
1283 : 5 : g_assert_null (list);
1284 : :
1285 : 5 : list = g_list_prepend (list, "test");
1286 : 5 : g_assert_nonnull (list);
1287 : :
1288 : 5 : g_clear_list (&list, NULL);
1289 : 5 : g_assert_null (list);
1290 : :
1291 : 5 : g_clear_list (&list, g_free);
1292 : 5 : g_assert_null (list);
1293 : :
1294 : 5 : list = g_list_prepend (list, g_malloc (16));
1295 : 5 : g_assert_nonnull (list);
1296 : :
1297 : 5 : g_clear_list (&list, g_free);
1298 : 5 : g_assert_null (list);
1299 : 5 : }
1300 : :
1301 : : static void
1302 : 5 : test_clear_slist (void)
1303 : : {
1304 : 5 : GSList *slist = NULL;
1305 : :
1306 : 5 : g_clear_slist (&slist, NULL);
1307 : 5 : g_assert_null (slist);
1308 : :
1309 : 5 : slist = g_slist_prepend (slist, "test");
1310 : 5 : g_assert_nonnull (slist);
1311 : :
1312 : 5 : g_clear_slist (&slist, NULL);
1313 : 5 : g_assert_null (slist);
1314 : :
1315 : 5 : g_clear_slist (&slist, g_free);
1316 : 5 : g_assert_null (slist);
1317 : :
1318 : 5 : slist = g_slist_prepend (slist, g_malloc (16));
1319 : 5 : g_assert_nonnull (slist);
1320 : :
1321 : 5 : g_clear_slist (&slist, g_free);
1322 : 5 : g_assert_null (slist);
1323 : 5 : }
1324 : :
1325 : : int
1326 : 25 : main (int argc,
1327 : : char *argv[])
1328 : : {
1329 : 25 : argv0 = argv[0];
1330 : :
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
1334 : : * Windows.
1335 : : */
1336 : 25 : g_set_prgname (argv[0]);
1337 : :
1338 : 25 : g_test_init (&argc, &argv, NULL);
1339 : :
1340 : 25 : g_test_add_func ("/utils/language-names", test_language_names);
1341 : 25 : g_test_add_func ("/utils/locale-variants", test_locale_variants);
1342 : 25 : g_test_add_func ("/utils/version", test_version);
1343 : 25 : g_test_add_func ("/utils/appname", test_appname);
1344 : 25 : g_test_add_func ("/utils/prgname-thread-safety", test_prgname_thread_safety);
1345 : 25 : g_test_add_func ("/utils/tmpdir", test_tmpdir);
1346 : 25 : g_test_add_func ("/utils/basic_bits", test_basic_bits);
1347 : 25 : g_test_add_func ("/utils/bits", test_bits);
1348 : 25 : g_test_add_func ("/utils/swap", test_swap);
1349 : 25 : g_test_add_func ("/utils/find-program", test_find_program);
1350 : 25 : g_test_add_func ("/utils/find-program-for-path", test_find_program_for_path);
1351 : 25 : g_test_add_func ("/utils/debug", test_debug);
1352 : 25 : g_test_add_func ("/utils/codeset", test_codeset);
1353 : 25 : g_test_add_func ("/utils/codeset2", test_codeset2);
1354 : 25 : g_test_add_func ("/utils/console-charset", test_console_charset);
1355 : 25 : g_test_add_func ("/utils/gettext", test_gettext);
1356 : 25 : g_test_add_func ("/utils/username", test_username);
1357 : 25 : g_test_add_func ("/utils/realname", test_realname);
1358 : 25 : g_test_add_func ("/utils/hostname", test_hostname);
1359 : : #ifdef G_OS_UNIX
1360 : 25 : g_test_add_func ("/utils/xdgdirs", test_xdg_dirs);
1361 : : #endif
1362 : 25 : g_test_add_func ("/utils/specialdir", test_special_dir);
1363 : 25 : g_test_add_func ("/utils/specialdir/desktop", test_desktop_special_dir);
1364 : 25 : g_test_add_func ("/utils/os-info", test_os_info);
1365 : 25 : g_test_add_func ("/utils/clear-pointer", test_clear_pointer);
1366 : 25 : g_test_add_func ("/utils/clear-pointer-cast", test_clear_pointer_cast);
1367 : 25 : g_test_add_func ("/utils/clear-pointer/side-effects", test_clear_pointer_side_effects);
1368 : 25 : g_test_add_func ("/utils/take-pointer", test_take_pointer);
1369 : 25 : g_test_add_func ("/utils/clear-source", test_clear_source);
1370 : 25 : g_test_add_func ("/utils/misc-mem", test_misc_mem);
1371 : 25 : g_test_add_func ("/utils/aligned-mem", test_aligned_mem);
1372 : 25 : g_test_add_func ("/utils/aligned-mem/subprocess/aligned_alloc_nz", aligned_alloc_nz);
1373 : 25 : g_test_add_func ("/utils/aligned-mem/subprocess/aligned_alloc_npot", aligned_alloc_npot);
1374 : 25 : g_test_add_func ("/utils/aligned-mem/subprocess/aligned_alloc_nmov", aligned_alloc_nmov);
1375 : 25 : g_test_add_func ("/utils/aligned-mem/alignment", test_aligned_mem_alignment);
1376 : 25 : g_test_add_func ("/utils/aligned-mem/zeroed", test_aligned_mem_zeroed);
1377 : 25 : g_test_add_func ("/utils/aligned-mem/free-sized", test_aligned_mem_free_sized);
1378 : 25 : g_test_add_func ("/utils/free-sized", test_free_sized);
1379 : 25 : g_test_add_func ("/utils/nullify", test_nullify);
1380 : 25 : g_test_add_func ("/utils/atexit", test_atexit);
1381 : 25 : g_test_add_func ("/utils/check-setuid", test_check_setuid);
1382 : 25 : g_test_add_func ("/utils/int-limits", test_int_limits);
1383 : 25 : g_test_add_func ("/utils/clear-list", test_clear_list);
1384 : 25 : g_test_add_func ("/utils/clear-slist", test_clear_slist);
1385 : :
1386 : 25 : return g_test_run ();
1387 : : }
|