LCOV - code coverage report
Current view: top level - glib/glib/tests - utils.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 621 640 97.0 %
Date: 2024-04-16 05:15:53 Functions: 53 57 93.0 %
Branches: 86 104 82.7 %

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

Generated by: LCOV version 1.14