mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
validate: Add including support in the structure file parser
Adding proper error reporting support Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-devtools/-/merge_requests/191>
This commit is contained in:
parent
d203f4251b
commit
0ffcacf325
7 changed files with 250 additions and 149 deletions
|
@ -49,7 +49,10 @@ void register_action_types (void);
|
||||||
G_GNUC_INTERNAL gboolean _action_check_and_set_printed (GstValidateAction *action);
|
G_GNUC_INTERNAL gboolean _action_check_and_set_printed (GstValidateAction *action);
|
||||||
G_GNUC_INTERNAL gboolean gst_validate_action_is_subaction (GstValidateAction *action);
|
G_GNUC_INTERNAL gboolean gst_validate_action_is_subaction (GstValidateAction *action);
|
||||||
G_GNUC_INTERNAL gboolean gst_validate_scenario_check_and_set_needs_clock_sync (GList *structures, GstStructure **meta);
|
G_GNUC_INTERNAL gboolean gst_validate_scenario_check_and_set_needs_clock_sync (GList *structures, GstStructure **meta);
|
||||||
G_GNUC_INTERNAL void _priv_validate_override_registry_deinit (void);
|
|
||||||
|
#define GST_VALIDATE_SCENARIO_SUFFIX ".scenario"
|
||||||
|
G_GNUC_INTERNAL gchar** gst_validate_scenario_get_include_paths(const gchar* relative_scenario);
|
||||||
|
G_GNUC_INTERNAL void _priv_validate_override_registry_deinit(void);
|
||||||
|
|
||||||
G_GNUC_INTERNAL GstValidateReportingDetails gst_validate_runner_get_default_reporting_details (GstValidateRunner *runner);
|
G_GNUC_INTERNAL GstValidateReportingDetails gst_validate_runner_get_default_reporting_details (GstValidateRunner *runner);
|
||||||
|
|
||||||
|
|
|
@ -360,7 +360,7 @@ _load_text_override_file (const gchar * filename)
|
||||||
{
|
{
|
||||||
gint ret = OK;
|
gint ret = OK;
|
||||||
GList *structs =
|
GList *structs =
|
||||||
gst_validate_utils_structs_parse_from_filename (filename, NULL);
|
gst_validate_utils_structs_parse_from_filename (filename, NULL, NULL);
|
||||||
|
|
||||||
if (structs) {
|
if (structs) {
|
||||||
GList *tmp;
|
GList *tmp;
|
||||||
|
|
|
@ -60,7 +60,6 @@
|
||||||
#include <gst/validate/gst-validate-override-registry.h>
|
#include <gst/validate/gst-validate-override-registry.h>
|
||||||
#include <gst/validate/gst-validate-pipeline-monitor.h>
|
#include <gst/validate/gst-validate-pipeline-monitor.h>
|
||||||
|
|
||||||
#define GST_VALIDATE_SCENARIO_SUFFIX ".scenario"
|
|
||||||
#define GST_VALIDATE_SCENARIO_DIRECTORY "scenarios"
|
#define GST_VALIDATE_SCENARIO_DIRECTORY "scenarios"
|
||||||
|
|
||||||
#define DEFAULT_SEEK_TOLERANCE (1 * GST_MSECOND) /* tolerance seek interval
|
#define DEFAULT_SEEK_TOLERANCE (1 * GST_MSECOND) /* tolerance seek interval
|
||||||
|
@ -397,7 +396,7 @@ gst_validate_action_get_type (void)
|
||||||
static gboolean execute_next_action (GstValidateScenario * scenario);
|
static gboolean execute_next_action (GstValidateScenario * scenario);
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_validate_scenario_load (GstValidateScenario * scenario,
|
gst_validate_scenario_load (GstValidateScenario * scenario,
|
||||||
const gchar * scenario_name, const gchar * relative_scenario);
|
const gchar * scenario_name);
|
||||||
|
|
||||||
static GstValidateAction *
|
static GstValidateAction *
|
||||||
_action_copy (GstValidateAction * act)
|
_action_copy (GstValidateAction * act)
|
||||||
|
@ -707,7 +706,7 @@ gst_validate_action_get_clocktime (GstValidateScenario * scenario,
|
||||||
|
|
||||||
_update_well_known_vars (scenario);
|
_update_well_known_vars (scenario);
|
||||||
strval =
|
strval =
|
||||||
gst_validate_replace_variables_in_string (scenario->priv->vars,
|
gst_validate_replace_variables_in_string (action, scenario->priv->vars,
|
||||||
tmpvalue);
|
tmpvalue);
|
||||||
if (!strval)
|
if (!strval)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -3231,7 +3230,7 @@ gst_validate_action_default_prepare_func (GstValidateAction * action)
|
||||||
GstValidateScenario *scenario = gst_validate_action_get_scenario (action);
|
GstValidateScenario *scenario = gst_validate_action_get_scenario (action);
|
||||||
|
|
||||||
_update_well_known_vars (scenario);
|
_update_well_known_vars (scenario);
|
||||||
gst_validate_structure_resolve_variables (action->structure,
|
gst_validate_structure_resolve_variables (action, action->structure,
|
||||||
scenario->priv->vars);
|
scenario->priv->vars);
|
||||||
for (i = 0; type->parameters[i].name; i++) {
|
for (i = 0; type->parameters[i].name; i++) {
|
||||||
if (type->parameters[i].types &&
|
if (type->parameters[i].types &&
|
||||||
|
@ -3683,22 +3682,6 @@ gst_validate_scenario_load_structures (GstValidateScenario * scenario,
|
||||||
gst_structure_get_int (structure, "max-dropped", &priv->max_dropped);
|
gst_structure_get_int (structure, "max-dropped", &priv->max_dropped);
|
||||||
scenario->description = gst_structure_copy (structure);
|
scenario->description = gst_structure_copy (structure);
|
||||||
|
|
||||||
continue;
|
|
||||||
} else if (!g_strcmp0 (type, "include")) {
|
|
||||||
const gchar *location = gst_structure_get_string (structure, "location");
|
|
||||||
|
|
||||||
if (!location) {
|
|
||||||
GST_ERROR_OBJECT (scenario,
|
|
||||||
"Mandatory field 'location' not present in structure: %"
|
|
||||||
GST_PTR_FORMAT, structure);
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gst_validate_scenario_load (scenario, location, origin_file)) {
|
|
||||||
GST_ERROR ("Failed including scenario %s", location);
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
} else if (!(action_type = _find_action_type (type))) {
|
} else if (!(action_type = _find_action_type (type))) {
|
||||||
if (gst_structure_has_field (structure, "optional-action-type")) {
|
if (gst_structure_has_field (structure, "optional-action-type")) {
|
||||||
|
@ -3765,26 +3748,12 @@ failed:
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
gchar **
|
||||||
_load_scenario_file (GstValidateScenario * scenario,
|
gst_validate_scenario_get_include_paths (const gchar * relative_scenario)
|
||||||
gchar * scenario_file, gboolean * is_config)
|
|
||||||
{
|
{
|
||||||
return gst_validate_scenario_load_structures (scenario,
|
gint n;
|
||||||
gst_validate_utils_structs_parse_from_filename (scenario_file, NULL),
|
|
||||||
is_config, scenario_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_validate_scenario_load (GstValidateScenario * scenario,
|
|
||||||
const gchar * scenario_name, const gchar * relative_scenario)
|
|
||||||
{
|
|
||||||
gchar **scenarios = NULL;
|
|
||||||
guint i;
|
|
||||||
gboolean found_actions = FALSE, is_config, ret = TRUE;
|
|
||||||
gchar *scenarios_path = g_strdup (g_getenv ("GST_VALIDATE_SCENARIOS_PATH"));
|
|
||||||
|
|
||||||
gchar **env_scenariodir;
|
gchar **env_scenariodir;
|
||||||
|
gchar *scenarios_path = g_strdup (g_getenv ("GST_VALIDATE_SCENARIOS_PATH"));
|
||||||
|
|
||||||
if (relative_scenario) {
|
if (relative_scenario) {
|
||||||
gchar *relative_dir = g_path_get_dirname (relative_scenario);
|
gchar *relative_dir = g_path_get_dirname (relative_scenario);
|
||||||
|
@ -3802,12 +3771,46 @@ gst_validate_scenario_load (GstValidateScenario * scenario,
|
||||||
0) : NULL;
|
0) : NULL;
|
||||||
g_free (scenarios_path);
|
g_free (scenarios_path);
|
||||||
|
|
||||||
|
n = g_strv_length (env_scenariodir);
|
||||||
|
env_scenariodir = g_realloc_n (env_scenariodir, n + 3, sizeof (gchar *));
|
||||||
|
env_scenariodir[n] = g_build_filename (g_get_user_data_dir (),
|
||||||
|
"gstreamer-" GST_API_VERSION, "validate",
|
||||||
|
GST_VALIDATE_SCENARIO_DIRECTORY, NULL);
|
||||||
|
env_scenariodir[n + 1] =
|
||||||
|
g_build_filename (GST_DATADIR, "gstreamer-" GST_API_VERSION, "validate",
|
||||||
|
GST_VALIDATE_SCENARIO_DIRECTORY, NULL);
|
||||||
|
env_scenariodir[n + 2] = NULL;
|
||||||
|
|
||||||
|
return env_scenariodir;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_load_scenario_file (GstValidateScenario * scenario,
|
||||||
|
gchar * scenario_file, gboolean * is_config)
|
||||||
|
{
|
||||||
|
return gst_validate_scenario_load_structures (scenario,
|
||||||
|
gst_validate_utils_structs_parse_from_filename (scenario_file,
|
||||||
|
(GstValidateGetIncludePathsFunc)
|
||||||
|
gst_validate_scenario_get_include_paths, NULL), is_config,
|
||||||
|
scenario_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_validate_scenario_load (GstValidateScenario * scenario,
|
||||||
|
const gchar * scenario_name)
|
||||||
|
{
|
||||||
|
gchar **scenarios = NULL;
|
||||||
|
guint i;
|
||||||
|
gboolean found_actions = FALSE, is_config, ret = TRUE;
|
||||||
|
gchar **include_paths = gst_validate_scenario_get_include_paths (NULL);
|
||||||
|
|
||||||
if (!scenario_name)
|
if (!scenario_name)
|
||||||
goto invalid_name;
|
goto invalid_name;
|
||||||
|
|
||||||
scenarios = g_strsplit (scenario_name, ":", -1);
|
scenarios = g_strsplit (scenario_name, ":", -1);
|
||||||
|
|
||||||
for (i = 0; scenarios[i]; i++) {
|
for (i = 0; scenarios[i]; i++) {
|
||||||
|
guint include_i;
|
||||||
gchar *lfilename = NULL, *tldir = NULL, *scenario_file = NULL;
|
gchar *lfilename = NULL, *tldir = NULL, *scenario_file = NULL;
|
||||||
|
|
||||||
/* First check if the scenario name is not a full path to the
|
/* First check if the scenario name is not a full path to the
|
||||||
|
@ -3827,46 +3830,17 @@ gst_validate_scenario_load (GstValidateScenario * scenario,
|
||||||
lfilename =
|
lfilename =
|
||||||
g_strdup_printf ("%s" GST_VALIDATE_SCENARIO_SUFFIX, scenarios[i]);
|
g_strdup_printf ("%s" GST_VALIDATE_SCENARIO_SUFFIX, scenarios[i]);
|
||||||
|
|
||||||
if (env_scenariodir) {
|
for (include_i = 0; include_paths[include_i]; include_i++) {
|
||||||
guint i;
|
tldir = g_build_filename (include_paths[include_i], lfilename, NULL);
|
||||||
|
if ((ret = _load_scenario_file (scenario, tldir, &is_config))) {
|
||||||
for (i = 0; env_scenariodir[i]; i++) {
|
scenario_file = tldir;
|
||||||
tldir = g_build_filename (env_scenariodir[i], lfilename, NULL);
|
break;
|
||||||
if ((ret = _load_scenario_file (scenario, tldir, &is_config))) {
|
|
||||||
scenario_file = tldir;
|
|
||||||
goto check_scenario;
|
|
||||||
}
|
|
||||||
g_free (tldir);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
tldir = g_build_filename ("data", "scenarios", lfilename, NULL);
|
|
||||||
|
|
||||||
if ((ret = _load_scenario_file (scenario, tldir, &is_config))) {
|
|
||||||
scenario_file = tldir;
|
|
||||||
goto check_scenario;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (tldir);
|
|
||||||
|
|
||||||
/* Try from local profiles */
|
|
||||||
tldir =
|
|
||||||
g_build_filename (g_get_user_data_dir (),
|
|
||||||
"gstreamer-" GST_API_VERSION, "validate",
|
|
||||||
GST_VALIDATE_SCENARIO_DIRECTORY, lfilename, NULL);
|
|
||||||
|
|
||||||
if (!(ret = _load_scenario_file (scenario, tldir, &is_config))) {
|
|
||||||
g_free (tldir);
|
g_free (tldir);
|
||||||
/* Try from system-wide profiles */
|
|
||||||
tldir = g_build_filename (GST_DATADIR, "gstreamer-" GST_API_VERSION,
|
|
||||||
"validate", GST_VALIDATE_SCENARIO_DIRECTORY, lfilename, NULL);
|
|
||||||
|
|
||||||
if (!(ret = _load_scenario_file (scenario, tldir, &is_config))) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scenario_file = tldir;
|
if (!ret)
|
||||||
|
goto error;
|
||||||
|
|
||||||
/* else check scenario */
|
/* else check scenario */
|
||||||
check_scenario:
|
check_scenario:
|
||||||
|
@ -3899,8 +3873,8 @@ gst_validate_scenario_load (GstValidateScenario * scenario,
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|
||||||
if (env_scenariodir)
|
if (include_paths)
|
||||||
g_strfreev (env_scenariodir);
|
g_strfreev (include_paths);
|
||||||
|
|
||||||
g_strfreev (scenarios);
|
g_strfreev (scenarios);
|
||||||
|
|
||||||
|
@ -4248,7 +4222,7 @@ gst_validate_scenario_new (GstValidateRunner *
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
GST_LOG ("Creating scenario %s", scenario_name);
|
GST_LOG ("Creating scenario %s", scenario_name);
|
||||||
if (!gst_validate_scenario_load (scenario, scenario_name, NULL)) {
|
if (!gst_validate_scenario_load (scenario, scenario_name)) {
|
||||||
g_object_unref (scenario);
|
g_object_unref (scenario);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -4413,7 +4387,9 @@ _parse_scenario (GFile * f, GKeyFile * kf)
|
||||||
|
|
||||||
if (g_str_has_suffix (path, GST_VALIDATE_SCENARIO_SUFFIX)) {
|
if (g_str_has_suffix (path, GST_VALIDATE_SCENARIO_SUFFIX)) {
|
||||||
GstStructure *meta = NULL;
|
GstStructure *meta = NULL;
|
||||||
GList *tmp, *structures = gst_validate_structs_parse_from_gfile (f);
|
GList *tmp, *structures = gst_validate_structs_parse_from_gfile (f,
|
||||||
|
(GstValidateGetIncludePathsFunc)
|
||||||
|
gst_validate_scenario_get_include_paths);
|
||||||
|
|
||||||
gst_validate_scenario_check_and_set_needs_clock_sync (structures, &meta);
|
gst_validate_scenario_check_and_set_needs_clock_sync (structures, &meta);
|
||||||
for (tmp = structures; tmp; tmp = tmp->next)
|
for (tmp = structures; tmp; tmp = tmp->next)
|
||||||
|
@ -6044,20 +6020,6 @@ register_action_types (void)
|
||||||
"setting the GST_DEBUG env variable",
|
"setting the GST_DEBUG env variable",
|
||||||
GST_VALIDATE_ACTION_TYPE_NONE);
|
GST_VALIDATE_ACTION_TYPE_NONE);
|
||||||
|
|
||||||
REGISTER_ACTION_TYPE ("include",
|
|
||||||
NULL, /* This is handled directly when loading a scenario */
|
|
||||||
((GstValidateActionParameter [])
|
|
||||||
{
|
|
||||||
{
|
|
||||||
.name = "location",
|
|
||||||
.description = "The location of the sub scenario to include.",
|
|
||||||
.mandatory = TRUE,
|
|
||||||
.types = "string"},
|
|
||||||
{NULL}
|
|
||||||
}),
|
|
||||||
"Include a sub scenario file.",
|
|
||||||
GST_VALIDATE_ACTION_TYPE_CONFIG);
|
|
||||||
|
|
||||||
REGISTER_ACTION_TYPE ("emit-signal", _execute_emit_signal,
|
REGISTER_ACTION_TYPE ("emit-signal", _execute_emit_signal,
|
||||||
((GstValidateActionParameter [])
|
((GstValidateActionParameter [])
|
||||||
{
|
{
|
||||||
|
|
|
@ -577,7 +577,8 @@ setup_quarks (void)
|
||||||
/* Parse file that contains a list of GStructures */
|
/* Parse file that contains a list of GStructures */
|
||||||
#define GST_STRUCT_LINE_CONTINUATION_CHARS ",{\\["
|
#define GST_STRUCT_LINE_CONTINUATION_CHARS ",{\\["
|
||||||
static GList *
|
static GList *
|
||||||
_file_get_structures (GFile * file, gchar ** err)
|
_file_get_structures (GFile * file, gchar ** err,
|
||||||
|
GstValidateGetIncludePathsFunc get_include_paths_func)
|
||||||
{
|
{
|
||||||
gsize size;
|
gsize size;
|
||||||
|
|
||||||
|
@ -587,23 +588,42 @@ _file_get_structures (GFile * file, gchar ** err)
|
||||||
gint lineno = 1, current_lineno;
|
gint lineno = 1, current_lineno;
|
||||||
GList *structures = NULL;
|
GList *structures = NULL;
|
||||||
GString *errstr = NULL;
|
GString *errstr = NULL;
|
||||||
|
gchar *red = NULL, *bold = NULL;
|
||||||
|
const gchar *endcolor = "";
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
errstr = g_string_new (NULL);
|
errstr = g_string_new (NULL);
|
||||||
|
|
||||||
/* TODO Handle GCancellable */
|
#if GLIB_CHECK_VERSION(2,50,0)
|
||||||
if (!g_file_load_contents (file, NULL, &content, &size, NULL, &error)) {
|
if (g_log_writer_supports_color (fileno (stderr))) {
|
||||||
GST_WARNING ("Failed to load contents: %d %s", error->code, error->message);
|
red = gst_debug_construct_term_color (GST_DEBUG_FG_RED);
|
||||||
g_free (content);
|
bold = gst_debug_construct_term_color (GST_DEBUG_BOLD);
|
||||||
g_error_free (error);
|
endcolor = "\033[0m";
|
||||||
return NULL;
|
} else
|
||||||
}
|
#endif
|
||||||
if (g_strcmp0 (content, "") == 0) {
|
{
|
||||||
g_free (content);
|
red = g_strdup ("");
|
||||||
return NULL;
|
bold = g_strdup ("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
filename = g_file_get_path (file);
|
filename = g_file_get_path (file);
|
||||||
|
/* TODO Handle GCancellable */
|
||||||
|
if (!g_file_load_contents (file, NULL, &content, &size, NULL, &error)) {
|
||||||
|
if (errstr && !get_include_paths_func)
|
||||||
|
g_string_append_printf (errstr,
|
||||||
|
"\n%s%s:%s %sFailed to load content%s\n | %s",
|
||||||
|
bold, filename, endcolor, red, endcolor, error->message);
|
||||||
|
else
|
||||||
|
GST_WARNING ("Failed to load contents: %d %s", error->code,
|
||||||
|
error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
if (g_strcmp0 (content, "") == 0) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
tmp = content;
|
tmp = content;
|
||||||
while (*tmp) {
|
while (*tmp) {
|
||||||
GString *l, *debug_line;
|
GString *l, *debug_line;
|
||||||
|
@ -673,13 +693,11 @@ _file_get_structures (GFile * file, gchar ** err)
|
||||||
|
|
||||||
structure = gst_structure_from_string (l->str, NULL);
|
structure = gst_structure_from_string (l->str, NULL);
|
||||||
if (structure == NULL) {
|
if (structure == NULL) {
|
||||||
GST_ERROR ("Could not parse structure at %s:%d-%d\n %s", filename,
|
|
||||||
current_lineno, lineno, debug_line->str);
|
|
||||||
|
|
||||||
if (errstr) {
|
if (errstr) {
|
||||||
g_string_append_printf (errstr,
|
g_string_append_printf (errstr,
|
||||||
"\n%s:%d-%d: Invalid structure\n%s",
|
"\n%s%s:%d-%d:%s %sInvalid structure%s\n%s",
|
||||||
filename, current_lineno, lineno, debug_line->str);
|
bold, filename, current_lineno, lineno, endcolor,
|
||||||
|
red, endcolor, debug_line->str);
|
||||||
|
|
||||||
if (strchr (debug_line->str, '\n'))
|
if (strchr (debug_line->str, '\n'))
|
||||||
g_string_append_printf (errstr, "\n > %s\n", l->str);
|
g_string_append_printf (errstr, "\n > %s\n", l->str);
|
||||||
|
@ -691,12 +709,107 @@ _file_get_structures (GFile * file, gchar ** err)
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setup_quarks ();
|
if (gst_structure_has_name (structure, "include")) {
|
||||||
gst_structure_id_set (structure,
|
gchar *included_err = NULL;
|
||||||
lineno_quark, G_TYPE_INT, current_lineno,
|
const gchar *location =
|
||||||
filename_quark, G_TYPE_STRING, filename,
|
gst_structure_get_string (structure, "location");
|
||||||
filename_quark, G_TYPE_STRING, debug_line->str, NULL);
|
|
||||||
structures = g_list_append (structures, structure);
|
if (location == NULL) {
|
||||||
|
if (errstr) {
|
||||||
|
g_string_append_printf (errstr,
|
||||||
|
"\n%s%s:%d-%d:%s %sMissing field 'location' in `include` structure%s\n%s",
|
||||||
|
bold, filename, current_lineno, lineno, endcolor,
|
||||||
|
red, endcolor, debug_line->str);
|
||||||
|
|
||||||
|
if (strchr (debug_line->str, '\n'))
|
||||||
|
g_string_append_printf (errstr, "\n > %s\n", l->str);
|
||||||
|
|
||||||
|
g_string_append_c (errstr, '\n');
|
||||||
|
} else {
|
||||||
|
g_string_free (l, TRUE);
|
||||||
|
g_string_free (debug_line, TRUE);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GFile *included = NULL;
|
||||||
|
GList *tmpstructures;
|
||||||
|
gchar **include_dirs = NULL;
|
||||||
|
|
||||||
|
if (!get_include_paths_func
|
||||||
|
&& g_str_has_suffix (location, GST_VALIDATE_SCENARIO_SUFFIX)) {
|
||||||
|
GST_INFO
|
||||||
|
("Trying to include a scenario, take into account scenario include dir");
|
||||||
|
|
||||||
|
get_include_paths_func = (GstValidateGetIncludePathsFunc)
|
||||||
|
gst_validate_scenario_get_include_paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_include_paths_func)
|
||||||
|
include_dirs = get_include_paths_func (g_file_peek_path (file));
|
||||||
|
|
||||||
|
if (!include_dirs) {
|
||||||
|
GFile *dir = g_file_get_parent (file);
|
||||||
|
included = g_file_resolve_relative_path (dir, location);
|
||||||
|
|
||||||
|
g_object_unref (dir);
|
||||||
|
} else {
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
for (i = 0; include_dirs[i]; i++) {
|
||||||
|
g_clear_object (&included);
|
||||||
|
included =
|
||||||
|
g_file_new_build_filename (include_dirs[i], location, NULL);
|
||||||
|
if (g_file_query_exists (included, NULL))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* We let the last attempt fail and report an error in the
|
||||||
|
* including code path */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_INFO ("%s including %s", g_file_peek_path (file),
|
||||||
|
g_file_peek_path (included));
|
||||||
|
|
||||||
|
tmpstructures = _file_get_structures (included, &included_err,
|
||||||
|
get_include_paths_func);
|
||||||
|
if (included_err) {
|
||||||
|
if (errstr) {
|
||||||
|
gchar *c;
|
||||||
|
|
||||||
|
g_string_append_printf (errstr,
|
||||||
|
"\n%s%s:%d-%d:%s %sError including %s%s\n%s",
|
||||||
|
bold, filename, current_lineno, lineno, endcolor,
|
||||||
|
red, location, endcolor, debug_line->str);
|
||||||
|
|
||||||
|
if (strchr (debug_line->str, '\n'))
|
||||||
|
g_string_append_printf (errstr, "\n > %s\n", l->str);
|
||||||
|
|
||||||
|
for (c = included_err; *c != '\0' && *(c + 1) != '\0'; c++) {
|
||||||
|
g_string_append_c (errstr, *c);
|
||||||
|
if (*c == '\n')
|
||||||
|
g_string_append (errstr, " | ");
|
||||||
|
}
|
||||||
|
g_free (included_err);
|
||||||
|
} else {
|
||||||
|
g_free (included_err);
|
||||||
|
g_string_free (l, TRUE);
|
||||||
|
g_string_free (debug_line, TRUE);
|
||||||
|
g_object_unref (included);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_object_unref (included);
|
||||||
|
structures = g_list_concat (structures, tmpstructures);
|
||||||
|
}
|
||||||
|
gst_structure_free (structure);
|
||||||
|
} else {
|
||||||
|
setup_quarks ();
|
||||||
|
gst_structure_id_set (structure,
|
||||||
|
lineno_quark, G_TYPE_INT, current_lineno,
|
||||||
|
filename_quark, G_TYPE_STRING, filename,
|
||||||
|
filename_quark, G_TYPE_STRING, debug_line->str, NULL);
|
||||||
|
structures = g_list_append (structures, structure);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_string_free (l, TRUE);
|
g_string_free (l, TRUE);
|
||||||
|
@ -711,6 +824,8 @@ done:
|
||||||
*err = g_string_free (errstr, errstr->len ? FALSE : TRUE);
|
*err = g_string_free (errstr, errstr->len ? FALSE : TRUE);
|
||||||
g_free (content);
|
g_free (content);
|
||||||
g_free (filename);
|
g_free (filename);
|
||||||
|
g_free (bold);
|
||||||
|
g_free (red);
|
||||||
return structures;
|
return structures;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
|
@ -722,23 +837,24 @@ failed:
|
||||||
}
|
}
|
||||||
|
|
||||||
static GList *
|
static GList *
|
||||||
_get_structures (const gchar * scenario_file, gchar ** file_path, gchar ** err)
|
_get_structures (const gchar * structured_file, gchar ** file_path,
|
||||||
|
GstValidateGetIncludePathsFunc get_include_paths_func, gchar ** err)
|
||||||
{
|
{
|
||||||
GFile *file = NULL;
|
GFile *file = NULL;
|
||||||
GList *structs = NULL;
|
GList *structs = NULL;
|
||||||
|
|
||||||
GST_DEBUG ("Trying to load %s", scenario_file);
|
GST_DEBUG ("Trying to load %s", structured_file);
|
||||||
if ((file = g_file_new_for_path (scenario_file)) == NULL) {
|
if ((file = g_file_new_for_path (structured_file)) == NULL) {
|
||||||
GST_WARNING ("%s wrong uri", scenario_file);
|
GST_WARNING ("%s wrong uri", structured_file);
|
||||||
if (err)
|
if (err)
|
||||||
*err = g_strdup_printf ("%s wrong uri", scenario_file);
|
*err = g_strdup_printf ("%s wrong uri", structured_file);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_path)
|
if (file_path)
|
||||||
*file_path = g_file_get_path (file);
|
*file_path = g_file_get_path (file);
|
||||||
|
|
||||||
structs = _file_get_structures (file, err);
|
structs = _file_get_structures (file, err, get_include_paths_func);
|
||||||
|
|
||||||
g_object_unref (file);
|
g_object_unref (file);
|
||||||
|
|
||||||
|
@ -749,17 +865,19 @@ _get_structures (const gchar * scenario_file, gchar ** file_path, gchar ** err)
|
||||||
* gst_validate_utils_structs_parse_from_filename: (skip):
|
* gst_validate_utils_structs_parse_from_filename: (skip):
|
||||||
*/
|
*/
|
||||||
GList *
|
GList *
|
||||||
gst_validate_utils_structs_parse_from_filename (const gchar * scenario_file,
|
gst_validate_utils_structs_parse_from_filename (const gchar * structured_file,
|
||||||
gchar ** file_path)
|
GstValidateGetIncludePathsFunc get_include_paths_func, gchar ** file_path)
|
||||||
{
|
{
|
||||||
GList *res;
|
GList *res;
|
||||||
gchar *err = NULL;
|
gchar *err = NULL;
|
||||||
|
|
||||||
res = _get_structures (scenario_file, file_path, &err);
|
res =
|
||||||
|
_get_structures (structured_file, file_path, get_include_paths_func,
|
||||||
|
&err);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
gst_validate_abort ("Could not get structures from %s:\n%s\n",
|
gst_validate_abort ("Could not get structures from %s:\n%s\n",
|
||||||
scenario_file, err);
|
structured_file, err);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -768,15 +886,16 @@ gst_validate_utils_structs_parse_from_filename (const gchar * scenario_file,
|
||||||
* gst_validate_structs_parse_from_gfile: (skip):
|
* gst_validate_structs_parse_from_gfile: (skip):
|
||||||
*/
|
*/
|
||||||
GList *
|
GList *
|
||||||
gst_validate_structs_parse_from_gfile (GFile * scenario_file)
|
gst_validate_structs_parse_from_gfile (GFile * structured_file,
|
||||||
|
GstValidateGetIncludePathsFunc get_include_paths_func)
|
||||||
{
|
{
|
||||||
gchar *err = NULL;
|
gchar *err = NULL;
|
||||||
GList *res;
|
GList *res;
|
||||||
|
|
||||||
res = _file_get_structures (scenario_file, &err);
|
res = _file_get_structures (structured_file, &err, get_include_paths_func);
|
||||||
if (err)
|
if (err)
|
||||||
gst_validate_abort ("Could not get structures from %s:\n%s\n",
|
gst_validate_abort ("Could not get structures from %s:\n%s\n",
|
||||||
g_file_get_uri (scenario_file), err);
|
g_file_get_uri (structured_file), err);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -1076,8 +1195,8 @@ gst_validate_element_matches_target (GstElement * element, GstStructure * s)
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar *
|
gchar *
|
||||||
gst_validate_replace_variables_in_string (GstStructure * local_vars,
|
gst_validate_replace_variables_in_string (gpointer source,
|
||||||
const gchar * in_string)
|
GstStructure * local_vars, const gchar * in_string)
|
||||||
{
|
{
|
||||||
gint varname_len;
|
gint varname_len;
|
||||||
GMatchInfo *match_info = NULL;
|
GMatchInfo *match_info = NULL;
|
||||||
|
@ -1111,8 +1230,8 @@ gst_validate_replace_variables_in_string (GstStructure * local_vars,
|
||||||
var_value = gst_structure_get_string (global_vars, varname);
|
var_value = gst_structure_get_string (global_vars, varname);
|
||||||
|
|
||||||
if (!var_value) {
|
if (!var_value) {
|
||||||
g_error
|
gst_validate_error_structure (source,
|
||||||
("Trying to use undefined variable : %s (\nlocals: %s\nglobals: %s\n)",
|
"Trying to use undefined variable `%s`.\n Available vars:\n - locals%s\n - globals%s\n",
|
||||||
varname, gst_structure_to_string (local_vars),
|
varname, gst_structure_to_string (local_vars),
|
||||||
gst_structure_to_string (global_vars));
|
gst_structure_to_string (global_vars));
|
||||||
|
|
||||||
|
@ -1143,9 +1262,14 @@ gst_validate_replace_variables_in_string (GstStructure * local_vars,
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
gpointer source;
|
||||||
|
GstStructure *local_vars;
|
||||||
|
} ReplaceData;
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_structure_set_variables (GQuark field_id, GValue * value,
|
_structure_set_variables (GQuark field_id, GValue * value, ReplaceData * data)
|
||||||
GstStructure * local_variables)
|
|
||||||
{
|
{
|
||||||
gchar *str;
|
gchar *str;
|
||||||
|
|
||||||
|
@ -1158,7 +1282,7 @@ _structure_set_variables (GQuark field_id, GValue * value,
|
||||||
|
|
||||||
for (i = 0; i < gst_value_list_get_size (value); i++)
|
for (i = 0; i < gst_value_list_get_size (value); i++)
|
||||||
_structure_set_variables (0, (GValue *) gst_value_list_get_value (value,
|
_structure_set_variables (0, (GValue *) gst_value_list_get_value (value,
|
||||||
i), local_variables);
|
i), data);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1166,7 +1290,8 @@ _structure_set_variables (GQuark field_id, GValue * value,
|
||||||
if (!G_VALUE_HOLDS_STRING (value))
|
if (!G_VALUE_HOLDS_STRING (value))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
str = gst_validate_replace_variables_in_string (local_variables,
|
str =
|
||||||
|
gst_validate_replace_variables_in_string (data->source, data->local_vars,
|
||||||
g_value_get_string (value));
|
g_value_get_string (value));
|
||||||
if (str) {
|
if (str) {
|
||||||
g_value_set_string (value, str);
|
g_value_set_string (value, str);
|
||||||
|
@ -1177,11 +1302,13 @@ _structure_set_variables (GQuark field_id, GValue * value,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_validate_structure_resolve_variables (GstStructure * structure,
|
gst_validate_structure_resolve_variables (gpointer source,
|
||||||
GstStructure * local_variables)
|
GstStructure * structure, GstStructure * local_variables)
|
||||||
{
|
{
|
||||||
|
ReplaceData d = { source ? source : structure, local_variables };
|
||||||
|
|
||||||
gst_structure_filter_and_map_in_place (structure,
|
gst_structure_filter_and_map_in_place (structure,
|
||||||
(GstStructureFilterMapFunc) _structure_set_variables, local_variables);
|
(GstStructureFilterMapFunc) _structure_set_variables, &d);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
typedef int (*GstValidateParseVariableFunc) (const gchar *name,
|
typedef int (*GstValidateParseVariableFunc) (const gchar *name,
|
||||||
double *value, gpointer user_data);
|
double *value, gpointer user_data);
|
||||||
|
|
||||||
|
typedef gchar** (*GstValidateGetIncludePathsFunc)(const gchar* includer_file);
|
||||||
|
|
||||||
GST_VALIDATE_API
|
GST_VALIDATE_API
|
||||||
gdouble gst_validate_utils_parse_expression (const gchar *expr,
|
gdouble gst_validate_utils_parse_expression (const gchar *expr,
|
||||||
GstValidateParseVariableFunc variable_func,
|
GstValidateParseVariableFunc variable_func,
|
||||||
|
@ -50,11 +52,14 @@ gchar ** gst_validate_utils_get_strv (GstStructure *str, const gchar *fiel
|
||||||
|
|
||||||
GST_VALIDATE_API
|
GST_VALIDATE_API
|
||||||
GList * gst_validate_utils_structs_parse_from_filename (const gchar * scenario_file,
|
GList * gst_validate_utils_structs_parse_from_filename (const gchar * scenario_file,
|
||||||
|
GstValidateGetIncludePathsFunc get_include_paths_func,
|
||||||
gchar **file_path);
|
gchar **file_path);
|
||||||
GST_VALIDATE_API
|
GST_VALIDATE_API
|
||||||
GstStructure * gst_validate_utils_test_file_get_meta (const gchar * testfile, gboolean use_fakesinks);
|
GstStructure * gst_validate_utils_test_file_get_meta (const gchar * testfile, gboolean use_fakesinks);
|
||||||
|
|
||||||
GST_VALIDATE_API
|
GST_VALIDATE_API
|
||||||
GList * gst_validate_structs_parse_from_gfile (GFile * scenario_file);
|
GList * gst_validate_structs_parse_from_gfile (GFile * scenario_file,
|
||||||
|
GstValidateGetIncludePathsFunc get_include_paths_func);
|
||||||
|
|
||||||
GST_VALIDATE_API
|
GST_VALIDATE_API
|
||||||
gboolean gst_validate_element_has_klass (GstElement * element, const gchar * klass);
|
gboolean gst_validate_element_has_klass (GstElement * element, const gchar * klass);
|
||||||
|
@ -74,9 +79,9 @@ void gst_validate_spin_on_fault_signals (void);
|
||||||
|
|
||||||
GST_VALIDATE_API
|
GST_VALIDATE_API
|
||||||
gboolean gst_validate_element_matches_target (GstElement * element, GstStructure * s);
|
gboolean gst_validate_element_matches_target (GstElement * element, GstStructure * s);
|
||||||
gchar * gst_validate_replace_variables_in_string (GstStructure * local_vars, const gchar * in_string);
|
gchar * gst_validate_replace_variables_in_string (gpointer incom, GstStructure * local_vars, const gchar * in_string);
|
||||||
GST_VALIDATE_API
|
GST_VALIDATE_API
|
||||||
void gst_validate_structure_resolve_variables (GstStructure *structure, GstStructure *local_variables);
|
void gst_validate_structure_resolve_variables (gpointer source, GstStructure *structure, GstStructure *local_variables);
|
||||||
void gst_validate_structure_set_variables_from_struct_file(GstStructure* vars, const gchar* struct_file);
|
void gst_validate_structure_set_variables_from_struct_file(GstStructure* vars, const gchar* struct_file);
|
||||||
void gst_validate_set_globals(GstStructure* structure);
|
void gst_validate_set_globals(GstStructure* structure);
|
||||||
GST_VALIDATE_API
|
GST_VALIDATE_API
|
||||||
|
|
|
@ -172,12 +172,12 @@ get_config_from_structures (GList * structures, GstStructure * local_vars,
|
||||||
(GstStructureForeachFunc) _set_vars_func, local_vars);
|
(GstStructureForeachFunc) _set_vars_func, local_vars);
|
||||||
gst_structure_free (structure);
|
gst_structure_free (structure);
|
||||||
} else {
|
} else {
|
||||||
gst_validate_structure_resolve_variables (structure, local_vars);
|
gst_validate_structure_resolve_variables (NULL, structure, local_vars);
|
||||||
result = g_list_append (result, structure);
|
result = g_list_append (result, structure);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!loaded_globals && gst_structure_has_name (structure, "set-globals")) {
|
if (!loaded_globals && gst_structure_has_name (structure, "set-globals")) {
|
||||||
gst_validate_structure_resolve_variables (structure, local_vars);
|
gst_validate_structure_resolve_variables (NULL, structure, local_vars);
|
||||||
gst_validate_set_globals (structure);
|
gst_validate_set_globals (structure);
|
||||||
}
|
}
|
||||||
gst_structure_free (structure);
|
gst_structure_free (structure);
|
||||||
|
@ -202,7 +202,8 @@ create_config (const gchar * config, const gchar * suffix)
|
||||||
|
|
||||||
local_vars = gst_structure_new_empty ("vars");
|
local_vars = gst_structure_new_empty ("vars");
|
||||||
structures =
|
structures =
|
||||||
gst_validate_utils_structs_parse_from_filename (config, &config_file);
|
gst_validate_utils_structs_parse_from_filename (config, NULL,
|
||||||
|
&config_file);
|
||||||
if (!structures) {
|
if (!structures) {
|
||||||
GstCaps *confs = NULL;
|
GstCaps *confs = NULL;
|
||||||
|
|
||||||
|
@ -344,6 +345,9 @@ gst_validate_get_config (const gchar * structname)
|
||||||
for (i = 0; tmp[i] != NULL; i++) {
|
for (i = 0; tmp[i] != NULL; i++) {
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
|
if (tmp[i][0] == '\0')
|
||||||
|
continue;
|
||||||
|
|
||||||
l = create_config (tmp[i], structname);
|
l = create_config (tmp[i], structname);
|
||||||
if (l)
|
if (l)
|
||||||
configs = g_list_concat (configs, l);
|
configs = g_list_concat (configs, l);
|
||||||
|
@ -553,7 +557,7 @@ gst_validate_setup_test_file (const gchar * testfile, gboolean use_fakesinks)
|
||||||
gst_validate_set_globals (NULL);
|
gst_validate_set_globals (NULL);
|
||||||
gst_validate_structure_set_variables_from_struct_file (NULL, testfile);
|
gst_validate_structure_set_variables_from_struct_file (NULL, testfile);
|
||||||
testfile_structs =
|
testfile_structs =
|
||||||
gst_validate_utils_structs_parse_from_filename (testfile, NULL);
|
gst_validate_utils_structs_parse_from_filename (testfile, NULL, NULL);
|
||||||
|
|
||||||
if (!testfile_structs)
|
if (!testfile_structs)
|
||||||
gst_validate_abort ("Could not load test file: %s", testfile);
|
gst_validate_abort ("Could not load test file: %s", testfile);
|
||||||
|
@ -578,7 +582,7 @@ gst_validate_setup_test_file (const gchar * testfile, gboolean use_fakesinks)
|
||||||
gst_validate_scenario_check_and_set_needs_clock_sync (testfile_structs, &res);
|
gst_validate_scenario_check_and_set_needs_clock_sync (testfile_structs, &res);
|
||||||
|
|
||||||
gst_validate_set_test_file_globals (res, testfile, use_fakesinks);
|
gst_validate_set_test_file_globals (res, testfile, use_fakesinks);
|
||||||
gst_validate_structure_resolve_variables (res, NULL);
|
gst_validate_structure_resolve_variables (NULL, res, NULL);
|
||||||
|
|
||||||
tool = gst_structure_get_string (res, "tool");
|
tool = gst_structure_get_string (res, "tool");
|
||||||
if (!tool)
|
if (!tool)
|
||||||
|
|
|
@ -8,7 +8,7 @@ GST_START_TEST (test_resolve_variables)
|
||||||
gst_structure_from_string ("vars, a=(string)1, b=(string)2", NULL);
|
gst_structure_from_string ("vars, a=(string)1, b=(string)2", NULL);
|
||||||
GstStructure *s2 = gst_structure_from_string ("test, n=\"$(a)/$(b)\"", NULL);
|
GstStructure *s2 = gst_structure_from_string ("test, n=\"$(a)/$(b)\"", NULL);
|
||||||
|
|
||||||
gst_validate_structure_resolve_variables (s2, s1);
|
gst_validate_structure_resolve_variables (NULL, s2, s1);
|
||||||
fail_unless_equals_string (gst_structure_get_string (s2, "n"), "1/2");
|
fail_unless_equals_string (gst_structure_get_string (s2, "n"), "1/2");
|
||||||
gst_structure_free (s1);
|
gst_structure_free (s1);
|
||||||
gst_structure_free (s2);
|
gst_structure_free (s2);
|
||||||
|
|
Loading…
Reference in a new issue