scenario: Add a TMPDIR global variables in scenarios

This also adds the notion of global variables which will be useable
in config files too.

And add some documentation about default variables in scenarios
This commit is contained in:
Thibault Saunier 2019-06-23 00:47:04 -04:00
parent db487b2732
commit 0e0928b0b7
4 changed files with 88 additions and 58 deletions

View file

@ -93,3 +93,16 @@ action types in the [`GstValidateScenario` section].
[`GST_STATE_NULL`]: GST_STATE_NULL
[`GstValidateScenario` section]: GstValidateScenario
## Default variables
Any action can use the default variables:
- `$(position)`: The current position in the pipeline as reported by
[gst_element_query_position()](gst_element_query_position)
- `$(duration)`: The current duration of the pipeline as reported by
[gst_element_query_duration()](gst_element_query_duration)
- `$(TMPDIR)`: The default temporary directory as returned by
[g_get_tmp_dir()](g_get_tmp_dir).
It is also possible to set variables in scenario with the `set-vars` action.

View file

@ -505,61 +505,6 @@ _update_well_known_vars (GstValidateScenario * scenario)
}
}
static gchar *
_replace_variables_in_string (GstValidateScenario * scenario,
GstValidateAction * action, const gchar * in_string)
{
GRegex *regex;
gint varname_len;
GMatchInfo *match_info;
const gchar *var_value;
gchar *tmpstring, *string = g_strdup (in_string);
_update_well_known_vars (scenario);
regex = g_regex_new ("\\$\\((\\w+)\\)", 0, 0, NULL);
g_regex_match (regex, string, 0, &match_info);
while (g_match_info_matches (match_info)) {
GRegex *replace_regex;
gchar *tmp, *varname, *pvarname = g_match_info_fetch (match_info, 0);
varname_len = strlen (pvarname);
varname = g_malloc (sizeof (gchar) * (varname_len - 2));
strncpy (varname, &pvarname[2], varname_len - 3);
varname[varname_len - 3] = '\0';
if (gst_structure_has_field_typed (scenario->priv->vars, varname,
G_TYPE_DOUBLE)) {
var_value = varname;
} else {
var_value = gst_structure_get_string (scenario->priv->vars, varname);
if (!var_value) {
g_error ("Trying to use undefined variable : %s (%s)", varname,
gst_structure_to_string (scenario->priv->vars));
return NULL;
}
}
tmp = g_strdup_printf ("\\$\\(%s\\)", varname);
replace_regex = g_regex_new (tmp, 0, 0, NULL);
g_free (tmp);
tmpstring = string;
string = g_regex_replace (replace_regex, string, -1, 0, var_value, 0, NULL);
GST_INFO_OBJECT (action, "Setting variable %s to %s", varname, var_value);
g_free (tmpstring);
g_regex_unref (replace_regex);
g_free (pvarname);
g_free (varname);
g_match_info_next (match_info, NULL);
}
g_match_info_free (match_info);
g_regex_unref (regex);
return string;
}
static gboolean
_set_variable_func (const gchar * name, double *value, gpointer user_data)
{
@ -635,7 +580,10 @@ gst_validate_action_get_clocktime (GstValidateScenario * scenario,
return -1;
}
strval = _replace_variables_in_string (scenario, action, tmpvalue);
_update_well_known_vars (scenario);
strval =
gst_validate_replace_variables_in_string (scenario->priv->vars,
tmpvalue);
if (!strval)
return FALSE;
@ -2974,8 +2922,7 @@ _structure_set_variables (GQuark field_id, GValue * value,
if (!scenario)
return TRUE;
str =
_replace_variables_in_string (scenario, action,
str = gst_validate_replace_variables_in_string (scenario->priv->vars,
g_value_get_string (value));
if (str) {
g_value_set_string (value, str);

View file

@ -46,6 +46,8 @@
#define PARSER_MAX_ARGUMENT_COUNT 10
static GRegex *_clean_structs_lines = NULL;
static GRegex *_variables_regex = NULL;
static GstStructure *global_vars = NULL;
typedef struct
{
@ -939,3 +941,70 @@ gst_validate_element_matches_target (GstElement * element, GstStructure * s)
return FALSE;
}
gchar *
gst_validate_replace_variables_in_string (GstStructure * local_vars,
const gchar * in_string)
{
gint varname_len;
GMatchInfo *match_info;
const gchar *var_value = NULL;
gchar *tmpstring, *string = g_strdup (in_string);
if (!_variables_regex)
_variables_regex = g_regex_new ("\\$\\((\\w+)\\)", 0, 0, NULL);
if (!global_vars) {
global_vars =
gst_structure_new ("vars", "TMPDIR", G_TYPE_STRING, g_get_tmp_dir (),
NULL);
}
g_regex_match (_variables_regex, string, 0, &match_info);
while (g_match_info_matches (match_info)) {
GRegex *replace_regex;
gchar *tmp, *varname, *pvarname = g_match_info_fetch (match_info, 0);
varname_len = strlen (pvarname);
varname = g_malloc (sizeof (gchar) * (varname_len - 2));
strncpy (varname, &pvarname[2], varname_len - 3);
varname[varname_len - 3] = '\0';
if (local_vars && gst_structure_has_field_typed (local_vars, varname,
G_TYPE_DOUBLE)) {
var_value = varname;
} else {
if (local_vars)
var_value = gst_structure_get_string (local_vars, varname);
if (!var_value)
var_value = gst_structure_get_string (global_vars, varname);
if (!var_value) {
g_error
("Trying to use undefined variable : %s (\nlocals: %s\nglobals: %s\n)",
varname, gst_structure_to_string (local_vars),
gst_structure_to_string (global_vars));
return NULL;
}
}
tmp = g_strdup_printf ("\\$\\(%s\\)", varname);
replace_regex = g_regex_new (tmp, 0, 0, NULL);
g_free (tmp);
tmpstring = string;
string = g_regex_replace (replace_regex, string, -1, 0, var_value, 0, NULL);
GST_INFO ("Setting variable %s to %s", varname, var_value);
g_free (tmpstring);
g_regex_unref (replace_regex);
g_free (pvarname);
g_free (varname);
g_match_info_next (match_info, NULL);
}
g_match_info_free (match_info);
return string;
}

View file

@ -69,5 +69,6 @@ void gst_validate_spin_on_fault_signals (void);
GST_VALIDATE_API
gboolean gst_validate_element_matches_target (GstElement * element, GstStructure * s);
gchar * gst_validate_replace_variables_in_string (GstStructure * local_vars, const gchar * in_string);
#endif