preset: Use GST_PRESET_PATH as an extension of the system path, not a replacement of the user path

First load all system presets, then all from the environment variable, then
from the app directory, then from the user directory. Any one in the chain
with the highest version completely replaces all previous ones, later ones
with lower versions are merged in without replacing existing presets.

This is basically the same behaviour as before, just that GST_PRESET_PATH is
inserted as another source of directories between the system and app presets.

It was added in ca08af1f17, but was
accidentially overriding the user preset path there. Which caused inconsistent
behaviour as new presets were still stored in the system path, just not loaded
from there. Meaning you could store a new preset (in the user path), just for
GstPreset to not find it anymore later (because it only looked in the
GST_PRESET_PATH instead of the user path).

https://bugzilla.gnome.org/show_bug.cgi?id=764034
This commit is contained in:
Sebastian Dröge 2016-03-22 19:04:59 +02:00
parent 94036e86c0
commit d7c8ce0947

View file

@ -349,6 +349,26 @@ preset_merge (GKeyFile * system, GKeyFile * user)
g_strfreev (groups);
}
typedef struct
{
GKeyFile *preset;
guint64 version;
} PresetAndVersion;
static gint
compare_preset_and_version (gconstpointer a, gconstpointer b,
gpointer user_data)
{
const PresetAndVersion *pa = a, *pb = b;
if (pa->version > pb->version)
return -1;
if (pa->version < pb->version)
return 1;
else
return 0;
}
/* reads the user and system presets files and merges them together. This
* function caches the GKeyFile on the element type. If there is no existing
* preset file, a new in-memory GKeyFile will be created. */
@ -366,12 +386,23 @@ preset_get_keyfile (GstPreset * preset)
guint64 version_user = G_GUINT64_CONSTANT (0);
guint64 version = G_GUINT64_CONSTANT (0);
gboolean merged = FALSE;
GKeyFile *in_user = NULL, *in_app = NULL, *in_system;
GKeyFile *in_user, *in_app = NULL, *in_system;
GQueue in_env = G_QUEUE_INIT;
gboolean have_env = FALSE;
const gchar *envvar;
/* try to load the user, app and system presets, we do this to get the
* versions of all files. */
preset_get_paths (preset, &preset_user_path, &preset_app_path,
&preset_system_path);
in_user = preset_open_and_parse_header (preset, preset_user_path,
&version_user);
if (preset_app_path) {
in_app = preset_open_and_parse_header (preset, preset_app_path,
&version_app);
}
envvar = g_getenv ("GST_PRESET_PATH");
if (envvar) {
gint i;
@ -380,27 +411,23 @@ preset_get_keyfile (GstPreset * preset)
for (i = 0; preset_dirs[i]; i++) {
gchar *preset_path = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s.prs",
preset_dirs[i], G_OBJECT_TYPE_NAME (preset));
GKeyFile *env_file;
guint64 env_version;
in_user = preset_open_and_parse_header (preset, preset_path,
&version_user);
env_file = preset_open_and_parse_header (preset, preset_path,
&env_version);
g_free (preset_path);
if (in_user)
break;
if (env_file) {
PresetAndVersion *pv = g_new (PresetAndVersion, 1);
pv->preset = env_file;
pv->version = env_version;
g_queue_push_tail (&in_env, pv);
have_env = TRUE;
}
}
g_strfreev (preset_dirs);
}
preset_get_paths (preset, &preset_user_path, &preset_app_path,
&preset_system_path);
if (!in_user) {
in_user = preset_open_and_parse_header (preset, preset_user_path,
&version_user);
}
if (preset_app_path) {
in_app = preset_open_and_parse_header (preset, preset_app_path,
&version_app);
}
in_system = preset_open_and_parse_header (preset, preset_system_path,
&version_system);
@ -409,8 +436,34 @@ preset_get_keyfile (GstPreset * preset)
presets = in_system;
version = version_system;
}
if (have_env) {
GList *l;
/* merge the ones from the environment paths. If any of them has a
* higher version, take that as the "master" version. Lower versions are
* then just merged in. */
g_queue_sort (&in_env, compare_preset_and_version, NULL);
/* highest version to lowest */
for (l = in_env.head; l; l = l->next) {
PresetAndVersion *pv = l->data;
if (version > pv->version) {
preset_merge (presets, pv->preset);
g_key_file_free (pv->preset);
} else {
if (presets)
g_key_file_free (presets);
presets = pv->preset;
version = pv->version;
}
g_free (pv);
}
g_queue_clear (&in_env);
}
if (in_app) {
/* if system version is higher, merge */
/* if system/env version is higher, merge */
if (version > version_app) {
preset_merge (presets, in_app);
g_key_file_free (in_app);
@ -422,7 +475,7 @@ preset_get_keyfile (GstPreset * preset)
}
}
if (in_user) {
/* if system or app version is higher, merge */
/* if system/env or app version is higher, merge */
if (version > version_user) {
preset_merge (presets, in_user);
g_key_file_free (in_user);