LCOV - code coverage report
Current view: top level - libgnucash/core-utils - gnc-environment.c (source / functions) Hit Total Coverage
Test: gnucash.info Lines: 81 95 85.3 %
Date: 2024-05-28 15:19:13 Functions: 3 3 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * gnc-environment.c:
       3                 :            :  *
       4                 :            :  * Copyright (C) 2013 Geert Janssens <geert@kobaltwit.be>
       5                 :            :  *
       6                 :            :  * This program is free software; you can redistribute it and/or
       7                 :            :  * modify it under the terms of the GNU General Public License as
       8                 :            :  * published by the Free Software Foundation; either version 2 of
       9                 :            :  * the License, or (at your option) any later version.
      10                 :            :  *
      11                 :            :  * This program is distributed in the hope that it will be useful,
      12                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14                 :            :  * GNU General Public License for more details.
      15                 :            :  *
      16                 :            :  * You should have received a copy of the GNU General Public License
      17                 :            :  * along with this program; if not, contact:
      18                 :            :  *
      19                 :            :  * Free Software Foundation           Voice:  +1-617-542-5942
      20                 :            :  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
      21                 :            :  * Boston, MA  02110-1301,  USA       gnu@gnu.org
      22                 :            :  */
      23                 :            : 
      24                 :            : #include <glib.h>
      25                 :            : #include <string.h>
      26                 :            : #include "gnc-environment.h"
      27                 :            : #include "gnc-path.h"
      28                 :            : 
      29                 :         24 : static gchar  *environment_expand(gchar *param)
      30                 :            : {
      31                 :            :     gchar *search_start;
      32                 :            :     gchar *opening_brace;
      33                 :            :     gchar *closing_brace;
      34                 :            :     gchar *result;
      35                 :            :     gchar *tmp;
      36                 :         24 :     gchar *expanded = NULL;
      37                 :            : 
      38                 :         24 :     if (!param)
      39                 :          0 :         return NULL;
      40                 :            : 
      41                 :            :     /* Set an initial return value, so we can always use g_strconcat below) */
      42                 :         24 :     result = g_strdup ("x");
      43                 :            : 
      44                 :            :     /* Look for matching pairs of { and }. Anything in between should be expanded */
      45                 :         24 :     search_start = param;
      46                 :         24 :     opening_brace = g_strstr_len (search_start, -1, "{");
      47                 :         24 :     closing_brace = g_strstr_len (search_start, -1, "}");
      48                 :            : 
      49                 :            :     /* Note: the test on valid braces is fairly simple:
      50                 :            :      *       * if no pair of opening/closing braces is found, no expansion occurs
      51                 :            :      *       * braces can't be nested, this will give unexpected results
      52                 :            :      *       * the string should contain no other braces than those used to mark
      53                 :            :      *         expandable variables, or unexpected results will be returned.
      54                 :            :      */
      55                 :         44 :     while ( opening_brace && closing_brace && (closing_brace > opening_brace) )
      56                 :            :     {
      57                 :            :         /* Found a first matching pair */
      58                 :            :         gchar *to_expand;
      59                 :            :         const gchar *env_val;
      60                 :            : 
      61                 :            :         /* If the string had characters before the opening {, copy them first */
      62                 :         20 :         if (opening_brace > search_start)
      63                 :            :         {
      64                 :          0 :             gchar *prefix = g_strndup (search_start, opening_brace - search_start);
      65                 :            : 
      66                 :          0 :             tmp = g_strconcat (result, prefix, NULL);
      67                 :          0 :             g_free (result);
      68                 :          0 :             result = tmp;
      69                 :          0 :             g_free (prefix);
      70                 :            :         }
      71                 :            : 
      72                 :            :         /* Expand the variable  we found and append it to the result */
      73                 :         20 :         to_expand = g_strndup (opening_brace + 1, closing_brace - opening_brace - 1);
      74                 :         20 :         env_val = g_getenv (to_expand);
      75                 :         20 :         tmp = g_strconcat (result, env_val, NULL);
      76                 :         20 :         g_free (result);
      77                 :         20 :         result = tmp;
      78                 :         20 :         g_free (to_expand);
      79                 :            : 
      80                 :            :         /* Look for matching pairs of { and }. Anything in between should be expanded */
      81                 :         20 :         search_start = closing_brace + 1;
      82                 :         20 :         opening_brace = g_strstr_len (search_start, -1, "{");
      83                 :         20 :         closing_brace = g_strstr_len (search_start, -1, "}");
      84                 :            :     }
      85                 :            : 
      86                 :            :     /* No more braces found, append the remaining characters */
      87                 :         24 :     tmp = g_strconcat (result, search_start, NULL);
      88                 :         24 :     g_free (result);
      89                 :         24 :     result = tmp;
      90                 :            : 
      91                 :            :     /* Remove the "x" from our result */
      92                 :         24 :     if (g_strcmp0 (result, "x"))
      93                 :         18 :         expanded = g_strdup (result + 1);
      94                 :         24 :     g_free (result);
      95                 :            : 
      96                 :         24 :     return expanded;
      97                 :            : }
      98                 :            : 
      99                 :            : static void
     100                 :          2 : gnc_environment_parse_one (const gchar *env_path)
     101                 :            : {
     102                 :          2 :     GKeyFile    *keyfile = g_key_file_new();
     103                 :            :     gchar **env_vars;
     104                 :            :     gsize param_count;
     105                 :            :     gint i;
     106                 :            :     gboolean got_keyfile;
     107                 :            : 
     108                 :          2 :     got_keyfile = g_key_file_load_from_file (keyfile, env_path, G_KEY_FILE_NONE, NULL);
     109                 :          2 :     if ( !got_keyfile )
     110                 :            :     {
     111                 :          1 :         g_key_file_free(keyfile);
     112                 :          1 :         return;
     113                 :            :     }
     114                 :            : 
     115                 :            :     /* Read the environment overrides and apply them */
     116                 :          1 :     env_vars = g_key_file_get_keys(keyfile, "Variables", &param_count, NULL);
     117                 :          8 :     for ( i = 0; i < param_count; i++ )
     118                 :            :     {
     119                 :            :         gchar **val_list;
     120                 :            :         gsize val_count;
     121                 :            :         gint j;
     122                 :          7 :         gchar *new_val = NULL, *tmp_val;
     123                 :            : 
     124                 :            :         /* For each variable, read its new value, optionally expand it and set/unset it */
     125                 :          7 :         val_list = g_key_file_get_string_list (keyfile, "Variables",
     126                 :          7 :                                                env_vars[i], &val_count,
     127                 :            :                                                NULL);
     128                 :          7 :         if ( val_count == 0 )
     129                 :          0 :             g_unsetenv (env_vars[i]);
     130                 :            :         else
     131                 :            :         {
     132                 :            :             /* Set an initial return value, so we can always use g_build_path below) */
     133                 :          7 :             tmp_val = g_strdup ("x");
     134                 :         31 :             for ( j = 0; j < val_count; j++ )
     135                 :            :             {
     136                 :         24 :                 gchar *expanded = environment_expand (val_list[j]);
     137                 :         24 :                 if (expanded && strlen(expanded))
     138                 :            :                 {
     139                 :         18 :                     new_val = g_build_path (G_SEARCHPATH_SEPARATOR_S, tmp_val, expanded, NULL);
     140                 :         18 :                     g_free (tmp_val);
     141                 :         18 :                     g_free(expanded);
     142                 :         18 :                     tmp_val = new_val;
     143                 :            :                 }
     144                 :            :             }
     145                 :          7 :             g_strfreev (val_list);
     146                 :            : 
     147                 :            :             /* Remove the "x" from our result */
     148                 :          7 :             if (g_strcmp0 (tmp_val, "x"))
     149                 :            :             {
     150                 :          7 :                 new_val = g_strdup (tmp_val + sizeof (G_SEARCHPATH_SEPARATOR_S));
     151                 :          7 :                 g_free (tmp_val);
     152                 :            :             }
     153                 :          7 :             if (!g_setenv (env_vars[i], new_val, TRUE))
     154                 :          0 :                 g_warning ("Couldn't properly override environment variable \"%s\". "
     155                 :            :                 "This may lead to unexpected results", env_vars[i]);
     156                 :          7 :             g_free(new_val);
     157                 :            :         }
     158                 :            :     }
     159                 :            : 
     160                 :          1 :     g_strfreev(env_vars);
     161                 :          1 :     g_key_file_free(keyfile);
     162                 :            : }
     163                 :            : 
     164                 :            : void
     165                 :          1 : gnc_environment_setup (void)
     166                 :            : {
     167                 :            :     gchar *config_path;
     168                 :            :     gchar *env_path;
     169                 :            :     gchar *env_parm;
     170                 :            : 
     171                 :            :     /* Export default parameters to the environment */
     172                 :          1 :     env_parm = gnc_path_get_prefix();
     173                 :          1 :     if (!g_setenv("GNC_HOME", env_parm, FALSE))
     174                 :          0 :         g_warning ("Couldn't set/override environment variable GNC_HOME.");
     175                 :          1 :     g_free (env_parm);
     176                 :          1 :     env_parm = gnc_path_get_bindir();
     177                 :          1 :     if (!g_setenv("GNC_BIN", env_parm, FALSE))
     178                 :          0 :         g_warning ("Couldn't set/override environment variable GNC_BIN.");
     179                 :          1 :     g_free (env_parm);
     180                 :          1 :     env_parm = gnc_path_get_pkglibdir();
     181                 :          1 :     if (!g_setenv("GNC_LIB", env_parm, FALSE))
     182                 :          0 :         g_warning ("Couldn't set/override environment variable GNC_LIB.");
     183                 :          1 :     g_free (env_parm);
     184                 :          1 :     env_parm = gnc_path_get_pkgdatadir();
     185                 :          1 :     if (!g_setenv("GNC_DATA", env_parm, FALSE))
     186                 :          0 :         g_warning ("Couldn't set/override environment variable GNC_DATA.");
     187                 :          1 :     g_free (env_parm);
     188                 :          1 :     env_parm = gnc_path_get_pkgsysconfdir();
     189                 :          1 :     if (!g_setenv("GNC_CONF", env_parm, FALSE))
     190                 :          0 :         g_warning ("Couldn't set/override environment variable GNC_CONF.");
     191                 :          1 :     g_free (env_parm);
     192                 :          1 :     env_parm = gnc_path_get_libdir();
     193                 :          1 :     if (!g_setenv("SYS_LIB", env_parm, FALSE))
     194                 :          0 :         g_warning ("Couldn't set/override environment variable SYS_LIB.");
     195                 :          1 :     g_free (env_parm);
     196                 :            : 
     197                 :          1 :     config_path = gnc_path_get_pkgsysconfdir();
     198                 :            : #ifdef G_OS_WIN32
     199                 :            :     {
     200                 :            :         /* unhide files without extension */
     201                 :            :         gchar *pathext = g_build_path(";", ".", g_getenv("PATHEXT"),
     202                 :            :                                       (gchar*) NULL);
     203                 :            :         g_setenv("PATHEXT", pathext, TRUE);
     204                 :            :         g_free(pathext);
     205                 :            :     }
     206                 :            : #endif
     207                 :            : 
     208                 :            :     /* Parse the environment file that got installed with gnucash */
     209                 :          1 :     env_path = g_build_filename (config_path, "environment", NULL);
     210                 :          1 :     gnc_environment_parse_one(env_path);
     211                 :          1 :     g_free (env_path);
     212                 :            : 
     213                 :            :     /* Parse local overrides for this file */
     214                 :          1 :     env_path = g_build_filename (config_path, "environment.local", NULL);
     215                 :          1 :     gnc_environment_parse_one(env_path);
     216                 :          1 :     g_free (env_path);
     217                 :          1 :     g_free (config_path);
     218                 :          1 : }

Generated by: LCOV version 1.14