From eef3392134b489fbff7c96046581c987ff7192bd Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 26 May 2020 00:01:51 +0200
Subject: Provided a way to relocate built binaries.

---
 configure.ac                    |  3 ++
 plugins/pychrysalide/pychrysa.c | 16 ++++++--
 src/core/paths.c                | 81 ++++++++++++++++++++++++++++++++++++++++-
 src/core/paths.h                |  6 +++
 src/gui/core/theme.c            | 28 +++++++-------
 src/hub.c                       | 32 +++++++++++++---
 src/main.c                      | 37 ++++++++++++++++---
 src/plugins/pglist.c            |  9 ++++-
 8 files changed, 179 insertions(+), 33 deletions(-)

diff --git a/configure.ac b/configure.ac
index 3759c75..a78cf1b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -100,6 +100,7 @@ AH_TEMPLATE([PIXMAPS_DIR], [Define the directory where the pictures will be inst
 AH_TEMPLATE([THEMES_DIR], [Define the main directory where all themes will be installed.])
 AH_TEMPLATE([PLUGINS_LIB_DIR], [Define the directory where the plugin librairies are installed.])
 AH_TEMPLATE([PLUGINS_DATA_DIR], [Define the directory where the plugin data is installed.])
+AH_TEMPLATE([BUILD_PREFIX_DIR], [Define the prefix for all installation directories.])
 AH_TEMPLATE([LOCALE_DIR], [Define the directory where the message catalogs are installed.])
 
 
@@ -172,6 +173,8 @@ if echo ${basedir} | grep -q '^NONE'; then
    AC_MSG_FAILURE([NONE found in \$prefix])
 fi
 
+AC_DEFINE_UNQUOTED(BUILD_PREFIX_DIR, "${basedir}")
+
 AC_DEFINE_UNQUOTED(LOCALE_DIR, "${basedir}/share/locale")
 
 
diff --git a/plugins/pychrysalide/pychrysa.c b/plugins/pychrysalide/pychrysa.c
index 96d61ae..29b0ee8 100644
--- a/plugins/pychrysalide/pychrysa.c
+++ b/plugins/pychrysalide/pychrysa.c
@@ -42,6 +42,7 @@
 #include <common/environment.h>
 #include <common/extstr.h>
 #include <core/core.h>
+#include <core/paths.h>
 #include <plugins/pglist.h>
 #include <plugins/self.h>
 
@@ -654,6 +655,9 @@ static void extend_python_path(const char *path)
 
 static void load_python_plugins(GPluginModule *plugin)
 {
+#ifdef DISCARD_LOCAL
+    char *edir;                             /* Répertoire de base effectif */
+#endif
     DIR *dir;                               /* Répertoire à parcourir      */
     char *paths;                            /* Emplacements de greffons    */
     char *save;                             /* Sauvegarde pour ré-entrance */
@@ -671,12 +675,18 @@ static void load_python_plugins(GPluginModule *plugin)
 
 #else
 
-    dir = opendir(PLUGINS_DATA_DIR G_DIR_SEPARATOR_S "python");
+    edir = get_effective_directory(PLUGINS_DATA_DIR G_DIR_SEPARATOR_S "python");
+    dir = opendir(edir);
+    free(edir);
 
     if (dir != NULL)
     {
          closedir(dir);
-         extend_python_path(PLUGINS_DATA_DIR G_DIR_SEPARATOR_S "python");
+
+         edir = get_effective_directory(PLUGINS_DATA_DIR G_DIR_SEPARATOR_S "python");
+         extend_python_path(edir);
+         free(edir);
+
     }
 
 #endif
@@ -942,7 +952,7 @@ void log_pychrysalide_exception(const char *prefix, ...)
         PyErr_Fetch(&err_type, &err_value, &err_traceback);
 
         if (err_value == NULL)
-            msg = stradd(msg, _("; no extra information is provided..."));
+            msg = stradd(msg, _(": no extra information is provided..."));
 
         else
         {
diff --git a/src/core/paths.c b/src/core/paths.c
index f58f46c..7f4765e 100644
--- a/src/core/paths.c
+++ b/src/core/paths.c
@@ -27,12 +27,20 @@
 #include <glib.h>
 #include <malloc.h>
 #include <stdio.h>
+#include <string.h>
 #include <unistd.h>
 
 
 #include <config.h>
 
 
+#include "../common/extstr.h"
+
+
+
+/* Eventuelle nouvelle racine de substitution */
+static const char *_new_prefix = NULL;
+
 
 /* Trouve le chemin d'accès complet à un fichier donné. */
 static char *find_file_in_directory(const char *, const char *);
@@ -41,6 +49,65 @@ static char *find_file_in_directory(const char *, const char *);
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : new = nouvelle racine pour les répertoires.                  *
+*                                                                             *
+*  Description : Enregistre un répertoire comme nouvelle base de construction.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void register_new_prefix(const char *new)
+{
+    _new_prefix = new;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : template = répertoire de travail visé.                       *
+*                                                                             *
+*  Description : Fournit le répertoire réel correspondant à une cible.        *
+*                                                                             *
+*  Retour      : Répertoire de travail effectif.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+char *get_effective_directory(const char *template)
+{
+    char *result;                           /* Répertoire à retourner      */
+    size_t len;                             /* Taille de comparaison       */
+
+    result = NULL;
+
+    if (_new_prefix == NULL)
+        goto use_default;
+
+    len = strlen(BUILD_PREFIX_DIR);
+
+    if (strncmp(template, BUILD_PREFIX_DIR, len) == 0)
+    {
+        result = strdup(_new_prefix);
+        result = stradd(result, template + len);
+    }
+
+ use_default:
+
+    if (result == NULL)
+        result = strdup(template);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : dirname  = répertoire de travail à fouiller.                 *
 *                filename = nom de fichier seul comme indice.                 *
 *                                                                             *
@@ -87,6 +154,7 @@ static char *find_file_in_directory(const char *dirname, const char *filename)
 char *find_pixmap_file(const char *filename)
 {
     char *result;                           /* Trouvaille à renvoyer       */
+    char *edir;                             /* Répertoire de base effectif */
 
     /**
      * On privilégie si possible les sources fraiches.
@@ -103,7 +171,11 @@ char *find_pixmap_file(const char *filename)
 #endif
 
     if (result == NULL)
-        result = find_file_in_directory(PIXMAPS_DIR, filename);
+    {
+        edir = get_effective_directory(PIXMAPS_DIR);
+        result = find_file_in_directory(edir, filename);
+        free(edir);
+    }
 
     return result;
 
@@ -129,6 +201,7 @@ char *find_plugin_data_file(const char *pgname, const char *filename)
 #ifndef DISCARD_LOCAL
     char *dirname;                          /* Répertoire à cibler         */
 #endif
+    char *edir;                             /* Répertoire de base effectif */
 
     /**
      * On privilégie si possible les sources fraiches.
@@ -150,7 +223,11 @@ char *find_plugin_data_file(const char *pgname, const char *filename)
 #endif
 
     if (result == NULL)
-        result = find_file_in_directory(PLUGINS_DATA_DIR, filename);
+    {
+        edir = get_effective_directory(PLUGINS_DATA_DIR);
+        result = find_file_in_directory(edir, filename);
+        free(edir);
+    }
 
     return result;
 
diff --git a/src/core/paths.h b/src/core/paths.h
index a755559..e6ce61f 100644
--- a/src/core/paths.h
+++ b/src/core/paths.h
@@ -26,6 +26,12 @@
 
 
 
+/* Enregistre un répertoire comme nouvelle base de construction. */
+void register_new_prefix(const char *);
+
+/* Fournit le répertoire réel correspondant à une cible. */
+char *get_effective_directory(const char *);
+
 /* Trouve le chemin d'accès complet à un fichier d'image. */
 char *find_pixmap_file(const char *);
 
diff --git a/src/gui/core/theme.c b/src/gui/core/theme.c
index 578bf9b..1345717 100644
--- a/src/gui/core/theme.c
+++ b/src/gui/core/theme.c
@@ -43,6 +43,7 @@
 #include "../../common/extstr.h"
 #include "../../common/xdg.h"
 #include "../../core/logs.h"
+#include "../../core/paths.h"
 
 
 
@@ -50,18 +51,6 @@
 static void look_for_editor_themes(const char *);
 
 
-/* Répertoires de recherche */
-static const char *_themes_directories[] = {
-
-#ifndef DISCARD_LOCAL
-    PACKAGE_SOURCE_DIR G_DIR_SEPARATOR_S "themes",
-#else
-    THEMES_DIR,
-#endif
-    NULL
-
-};
-
 /* Liste de thèmes utilisables */
 static GEditorTheme **_themes = NULL;
 static size_t _theme_count = 0;
@@ -84,7 +73,9 @@ void load_all_themes(void)
 {
     char *suffix;                           /* Fin du répertoire personnel */
     char *owndir;                           /* Thèmes personnels ?         */
-    const char **iter;                      /* Boucle de parcours          */
+#ifdef DISCARD_LOCAL
+    char *edir;                             /* Répertoire de base effectif */
+#endif
 
     /* Répertoire de l'utilisateur en premier ! */
 
@@ -104,8 +95,15 @@ void load_all_themes(void)
 
     /* Parcours des autres répertoires classiques au besoin */
 
-    for (iter = _themes_directories; *iter != NULL; iter++)
-        look_for_editor_themes(*iter);
+#ifndef DISCARD_LOCAL
+    look_for_editor_themes(PACKAGE_SOURCE_DIR G_DIR_SEPARATOR_S "themes");
+#else
+
+    edir = get_effective_directory(THEMES_DIR);
+    look_for_editor_themes(edir);
+    free(edir);
+
+#endif
 
 }
 
diff --git a/src/hub.c b/src/hub.c
index 8e8840c..b77bdb8 100644
--- a/src/hub.c
+++ b/src/hub.c
@@ -43,6 +43,7 @@
 #include "analysis/db/server.h"
 #include "core/global.h"
 #include "core/logs.h"
+#include "core/paths.h"
 
 
 
@@ -207,6 +208,8 @@ static void show_hub_help(const char *name)
 
 static void show_hub_version(void)
 {
+    char *edir;                             /* Répertoire de base effectif */
+
     printf("\n");
 
     printf("-o-  Chrysalide Hub r%u  -o-\n", REVISION);
@@ -214,11 +217,25 @@ static void show_hub_version(void)
 
     printf("\n");
 
-    printf(_("Pictures directory: %s\n"), PIXMAPS_DIR);
-    printf(_("Themes directory: %s\n"), THEMES_DIR);
-    printf(_("Plugins library directory: %s\n"), PLUGINS_LIB_DIR);
-    printf(_("Plugins data directory: %s\n"), PLUGINS_DATA_DIR);
-    printf(_("Locale directory: %s\n"), LOCALE_DIR);
+    edir = get_effective_directory(PIXMAPS_DIR);
+    printf(_("Pictures directory: %s\n"), edir);
+    free(edir);
+
+    edir = get_effective_directory(THEMES_DIR);
+    printf(_("Themes directory: %s\n"), edir);
+    free(edir);
+
+    edir = get_effective_directory(PLUGINS_LIB_DIR);
+    printf(_("Plugins library directory: %s\n"), edir);
+    free(edir);
+
+    edir = get_effective_directory(PLUGINS_DATA_DIR);
+    printf(_("Plugins data directory: %s\n"), edir);
+    free(edir);
+
+    edir = get_effective_directory(LOCALE_DIR);
+    printf(_("Locale directory: %s\n"), edir);
+    free(edir);
 
     printf("\n");
 
@@ -247,6 +264,7 @@ int main(int argc, char **argv)
     LogMessageType verbosity;               /* Niveau de filtre de message */
     int index;                              /* Indice d'argument           */
     int ret;                                /* Bilan d'un appel            */
+    char *edir;                             /* Répertoire de base effectif */
 
     static struct option long_options[] = {
         { "help",       no_argument,        NULL,   'h' },
@@ -327,7 +345,9 @@ int main(int argc, char **argv)
     /* Lancement des choses sérieuses */
 
     setlocale(LC_ALL, "");
-    bindtextdomain(PACKAGE, LOCALE_DIR);
+    edir = get_effective_directory(LOCALE_DIR);
+    bindtextdomain(PACKAGE, edir);
+    free(edir);
     textdomain(PACKAGE);
 
     /* Initialisation de GTK */
diff --git a/src/main.c b/src/main.c
index 7adab42..1b50615 100644
--- a/src/main.c
+++ b/src/main.c
@@ -47,6 +47,7 @@
 #include "core/global.h"
 #include "core/logs.h"
 #include "core/params.h"
+#include "core/paths.h"
 #include "core/queue.h"
 #include "glibext/delayed.h"
 #include "gui/editor.h"
@@ -132,6 +133,8 @@ static void show_chrysalide_help(const char *name)
 
 static void show_chrysalide_version(void)
 {
+    char *edir;                             /* Répertoire de base effectif */
+
     printf("\n");
 
     printf("-o-  Chrysalide r%u  -o-\n", REVISION);
@@ -139,11 +142,25 @@ static void show_chrysalide_version(void)
 
     printf("\n");
 
-    printf(_("Pictures directory: %s\n"), PIXMAPS_DIR);
-    printf(_("Themes directory: %s\n"), THEMES_DIR);
-    printf(_("Plugins library directory: %s\n"), PLUGINS_LIB_DIR);
-    printf(_("Plugins data directory: %s\n"), PLUGINS_DATA_DIR);
-    printf(_("Locale directory: %s\n"), LOCALE_DIR);
+    edir = get_effective_directory(PIXMAPS_DIR);
+    printf(_("Pictures directory: %s\n"), edir);
+    free(edir);
+
+    edir = get_effective_directory(THEMES_DIR);
+    printf(_("Themes directory: %s\n"), edir);
+    free(edir);
+
+    edir = get_effective_directory(PLUGINS_LIB_DIR);
+    printf(_("Plugins library directory: %s\n"), edir);
+    free(edir);
+
+    edir = get_effective_directory(PLUGINS_DATA_DIR);
+    printf(_("Plugins data directory: %s\n"), edir);
+    free(edir);
+
+    edir = get_effective_directory(LOCALE_DIR);
+    printf(_("Locale directory: %s\n"), edir);
+    free(edir);
 
     printf("\n");
 
@@ -174,6 +191,7 @@ int main(int argc, char **argv)
     char *prj_filename;                     /* Chemin vers un projet       */
     int index;                              /* Indice d'argument           */
     int ret;                                /* Bilan d'un appel            */
+    char *edir;                             /* Répertoire de base effectif */
     bool status;                            /* Bilan d'opérations          */
     GtkWidget *editor;                      /* Fenêtre graphique           */
     GGenConfig *config;                     /* Configuration globale       */
@@ -188,6 +206,7 @@ int main(int argc, char **argv)
         { "batch",      no_argument,        NULL,   'b' },
         { "save",       no_argument,        NULL,   's' },
         { "project",    required_argument,  NULL,   'p' },
+        { "new-prefix", required_argument,  NULL,   'n' },
         { NULL,         0,                  NULL,   0 }
     };
 
@@ -241,6 +260,10 @@ int main(int argc, char **argv)
                 prj_filename = optarg;
                 break;
 
+            case 'n':
+                register_new_prefix(optarg);
+                break;
+
         }
 
     }
@@ -264,7 +287,9 @@ int main(int argc, char **argv)
     /* Lancement des choses sérieuses */
 
     setlocale(LC_ALL, "");
-    bindtextdomain(PACKAGE, LOCALE_DIR);
+    edir = get_effective_directory(LOCALE_DIR);
+    bindtextdomain(PACKAGE, edir);
+    free(edir);
     textdomain(PACKAGE);
 
     /* Initialisation de GTK */
diff --git a/src/plugins/pglist.c b/src/plugins/pglist.c
index 97fc931..cb366fe 100644
--- a/src/plugins/pglist.c
+++ b/src/plugins/pglist.c
@@ -37,6 +37,7 @@
 
 #include "plugin-int.h"
 #include "../common/extstr.h"
+#include "../core/paths.h"
 
 
 
@@ -73,12 +74,18 @@ static void on_plugin_ref_toggle(gpointer, GPluginModule *, gboolean);
 
 bool init_all_plugins(bool load)
 {
+#ifdef DISCARD_LOCAL
+    char *edir;                             /* Répertoire de base effectif */
+#endif
+
     g_rw_lock_init(&_pg_lock);
 
 #ifndef DISCARD_LOCAL
     browse_directory_for_plugins(PACKAGE_SOURCE_DIR "/plugins");
 #else
-    browse_directory_for_plugins(PLUGINS_LIB_DIR);
+    edir = get_effective_directory(PLUGINS_LIB_DIR);
+    browse_directory_for_plugins(edir);
+    free(edir);
 #endif
 
     if (load)
-- 
cgit v0.11.2-87-g4458