From abb5f2cc2f9f424dc305d15ea3d0627667785a74 Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Thu, 19 Feb 2015 08:51:20 +0100 Subject: [PATCH] ges-launch: Implement a new parser for the commandline. Summary: + flex-based lexing and manual simplistic parsing. Test Plan: Use that stuff to make awesome things, see if it breaks. --- .gitignore | 2 + configure.ac | 2 + tools/Makefile.am | 11 +++- tools/ges-launch.c | 73 ++++++++++++++++++++++++ tools/ges-structure-parser.c | 107 +++++++++++++++++++++++++++++++++++ tools/ges-structure-parser.h | 60 ++++++++++++++++++++ tools/parse.l | 32 +++++++++++ 7 files changed, 285 insertions(+), 2 deletions(-) create mode 100644 tools/ges-structure-parser.c create mode 100644 tools/ges-structure-parser.h create mode 100644 tools/parse.l diff --git a/.gitignore b/.gitignore index 251ab62812..054b2bf78a 100644 --- a/.gitignore +++ b/.gitignore @@ -75,6 +75,8 @@ log /tests/check/nle/nlesource /tools/ges-launch-1.0 +tools/lex.priv_ges_parse_yy.c +tools/parse_lex.h /tests/check/ges/project /tests/examples/assets diff --git a/configure.ac b/configure.ac index 0ee1243fdd..9f5649d27a 100644 --- a/configure.ac +++ b/configure.ac @@ -81,6 +81,8 @@ AG_GST_ARG_WITH_PACKAGE_ORIGIN AG_GST_PKG_CONFIG_PATH +AG_GST_FLEX_CHECK + dnl *** checks for platform *** dnl * hardware/architecture * diff --git a/tools/Makefile.am b/tools/Makefile.am index 49d18a01a5..6349bfadc8 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -3,9 +3,13 @@ bin_PROGRAMS = ges-launch-@GST_API_VERSION@ AM_CFLAGS = -I$(top_srcdir) $(GST_PBUTILS_CFLAGS) $(GST_CFLAGS) $(GIO_CFLAGS) $(GST_VALIDATE_CFLAGS) LDADD = $(top_builddir)/ges/libges-@GST_API_VERSION@.la $(GST_PBUTILS_LIBS) $(GST_LIBS) $(GIO_LIBS) $(GST_VALIDATE_LIBS) -noinst_HEADERS = ges-validate.h +noinst_HEADERS = ges-validate.h ges-structure-parser.h -ges_launch_@GST_API_VERSION@_SOURCES = ges-validate.c ges-launch.c +ges_launch_@GST_API_VERSION@_SOURCES = ges-validate.c ges-launch.c ges-structure-parser.c + +nodist_ges_launch_@GST_API_VERSION@_SOURCES = lex.priv_ges_parse_yy.c parse_lex.h + +CLEANFILES = lex.priv_ges_parse_yy.c Android.mk: Makefile.am $(BUILT_SOURCES) androgenizer \ @@ -17,3 +21,6 @@ Android.mk: Makefile.am $(BUILT_SOURCES) -:LDFLAGS -lges-@GST_API_VERSION@ $(GST_PBUTILS_LIBS) $(GST_LIBS) \ -:PASSTHROUGH LOCAL_ARM_MODE:=arm \ > $@ + +lex.priv_ges_parse_yy.c parse_lex.h: parse.l + $(AM_V_GEN)$(FLEX_PATH) --header-file=parse_lex.h -Ppriv_ges_parse_yy $^ diff --git a/tools/ges-launch.c b/tools/ges-launch.c index 4f8738bb0e..7b7ffd26d8 100644 --- a/tools/ges-launch.c +++ b/tools/ges-launch.c @@ -35,6 +35,8 @@ #include #endif +#include "ges-structure-parser.h" +#include "parse_lex.h" /* GLOBAL VARIABLE */ static guint repeat = 0; @@ -699,6 +701,65 @@ _add_media_path (const gchar * option_name, const gchar * value, return TRUE; } +/* g_free after usage */ +static gchar * +sanitize_argument (gchar * arg) +{ + char *equal_index = strstr (arg, "="); + char *space_index = strstr (arg, " "); + gchar *new_string = g_malloc (sizeof (gchar) * (strlen (arg) + 3)); + gchar *tmp_string = new_string; + + if (!space_index) + return g_strdup (arg); + + if (!equal_index || equal_index > space_index) + return g_strdup_printf ("\"%s\"", arg); + + for (arg = arg; *arg != '\0'; arg++) { + *tmp_string = *arg; + tmp_string += 1; + if (*arg == '=') { + *tmp_string = '"'; + tmp_string += 1; + } + } + *tmp_string = '"'; + tmp_string += 1; + *tmp_string = '\0'; + + return new_string; +} + +static GESStructureParser * +_parse_timeline (int argc, char **argv) +{ + gint i; + yyscan_t scanner; + gchar *string = g_strdup (" "); + GESStructureParser *parser = ges_structure_parser_new (); + + priv_ges_parse_yylex_init_extra (parser, &scanner); + for (i = 1; i < argc; i++) { + gchar *new_string; + gchar *sanitized = sanitize_argument (argv[i]); + + new_string = g_strconcat (string, " ", sanitized, NULL); + + g_free (sanitized); + g_free (string); + string = new_string; + } + + priv_ges_parse_yy_scan_string (string, scanner); + priv_ges_parse_yylex (scanner); + g_free (string); + priv_ges_parse_yylex_destroy (scanner); + + ges_structure_parser_end_of_file (parser); + return parser; +} + int main (int argc, gchar ** argv) { @@ -716,6 +777,7 @@ main (int argc, gchar ** argv) gchar *videosink = NULL, *audiosink = NULL; gboolean inspect_action_type = FALSE; gchar *encoding_profile = NULL; + GESStructureParser *parser; GOptionEntry options[] = { {"thumbnail", 'm', 0.0, G_OPTION_ARG_DOUBLE, &thumbinterval, @@ -820,6 +882,8 @@ main (int argc, gchar ** argv) g_option_context_add_group (ctx, gst_init_get_option_group ()); g_option_context_add_group (ctx, ges_init_get_option_group ()); + g_option_context_set_ignore_unknown_options (ctx, TRUE); + if (!g_option_context_parse (ctx, &argc, &argv, &err)) { g_printerr ("Error initializing: %s\n", err->message); g_option_context_free (ctx); @@ -833,6 +897,15 @@ main (int argc, gchar ** argv) exit (1); } + parser = _parse_timeline (argc, argv); + + { + GList *tmp; + for (tmp = parser->structures; tmp; tmp = tmp->next) { + /* Do stuff here */ + } + } + if (list_transitions) { print_transition_list (); exit (0); diff --git a/tools/ges-structure-parser.c b/tools/ges-structure-parser.c new file mode 100644 index 0000000000..aa33bfe5c7 --- /dev/null +++ b/tools/ges-structure-parser.c @@ -0,0 +1,107 @@ +/* GStreamer Editing Services + * + * Copyright (C) <2015> Mathieu Duponchelle + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "ges-structure-parser.h" + +G_DEFINE_TYPE (GESStructureParser, ges_structure_parser, G_TYPE_OBJECT); + +static void +ges_structure_parser_init (GESStructureParser * self) +{ +} + +static void +ges_structure_parser_class_init (GESStructureParserClass * klass) +{ +} + +void +ges_structure_parser_parse_string (GESStructureParser * self, + const gchar * text, gboolean is_symbol) +{ + gchar *new_string = NULL; + + if (self->current_string) { + new_string = g_strconcat (self->current_string, text, NULL); + } else if (is_symbol) { + new_string = g_strdup (text); + } + + g_free (self->current_string); + self->current_string = new_string; +} + +void +ges_structure_parser_parse_default (GESStructureParser * self, + const gchar * text) +{ + gchar *new_string = NULL; + + if (self->add_comma && self->current_string) { + new_string = g_strconcat (self->current_string, ",", text, NULL); + g_free (self->current_string); + self->current_string = new_string; + self->add_comma = FALSE; + } else { + ges_structure_parser_parse_string (self, text, FALSE); + } +} + +void +ges_structure_parser_parse_whitespace (GESStructureParser * self) +{ + self->add_comma = TRUE; +} + +static void +_finish_structure (GESStructureParser * self) +{ + if (self->current_string) { + GstStructure *structure = + gst_structure_new_from_string (self->current_string); + self->structures = g_list_append (self->structures, structure); + g_free (self->current_string); + self->current_string = NULL; + } +} + +void +ges_structure_parser_end_of_file (GESStructureParser * self) +{ + _finish_structure (self); +} + +void +ges_structure_parser_parse_symbol (GESStructureParser * self, + const gchar * symbol) +{ + _finish_structure (self); + + while (*symbol == '-' || *symbol == ' ') + symbol++; + ges_structure_parser_parse_string (self, symbol, TRUE); + self->add_comma = TRUE; +} + +GESStructureParser * +ges_structure_parser_new (void) +{ + return (g_object_new (GES_TYPE_STRUCTURE_PARSER, NULL)); +} diff --git a/tools/ges-structure-parser.h b/tools/ges-structure-parser.h new file mode 100644 index 0000000000..acdb94b666 --- /dev/null +++ b/tools/ges-structure-parser.h @@ -0,0 +1,60 @@ +/* GStreamer Editing Services + * + * Copyright (C) <2015> Mathieu Duponchelle + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef _GES_STRUCTURE_PARSER_H +#define _GES_STRUCTURE_PARSER_H + +#include +#include + +G_BEGIN_DECLS + +#define GES_TYPE_STRUCTURE_PARSER ges_structure_parser_get_type() + +typedef struct _GESStructureParser GESStructureParser; +typedef struct _GESStructureParserClass GESStructureParserClass; + +struct _GESStructureParser +{ + GObject parent; + GList *structures; + + /*< private > */ + gchar *current_string; + gboolean add_comma; +}; + +struct _GESStructureParserClass +{ + /*< private >*/ + GObjectClass parent_class; +}; + +GType ges_structure_parser_get_type (void) G_GNUC_CONST; + +void ges_structure_parser_parse_string (GESStructureParser *self, const gchar *string, gboolean is_symbol); +void ges_structure_parser_parse_default (GESStructureParser *self, const gchar *text); +void ges_structure_parser_parse_whitespace (GESStructureParser *self); +void ges_structure_parser_parse_symbol (GESStructureParser *self, const gchar *symbol); +void ges_structure_parser_end_of_file (GESStructureParser *self); + +GESStructureParser *ges_structure_parser_new(void); +G_END_DECLS + +#endif /* _GES_STRUCTURE_PARSER_H */ diff --git a/tools/parse.l b/tools/parse.l new file mode 100644 index 0000000000..dec52ba29d --- /dev/null +++ b/tools/parse.l @@ -0,0 +1,32 @@ +%{ +#include "ges-structure-parser.h" + +%} + +%option noyywrap +%option nounput +%option reentrant +%option extra-type="GESStructureParser *" +%option never-interactive +%option noinput + +%% + +\"(\\.|[^"])*\" { + ges_structure_parser_parse_string (yyextra, yytext, FALSE); +} + +[ ]+--clip[ ]+|[ ]+-c[ ]+|[ ]+--transition[ ]+|[ ]+-t[ ]+|[ ]+--effect[ ]+|[ ]+-e[ ]+ { + ges_structure_parser_parse_symbol (yyextra, yytext); +} + +[ \t\n]+ { + ges_structure_parser_parse_whitespace (yyextra); +} + +. { + /* add everything else */ + ges_structure_parser_parse_default (yyextra, yytext); +} + +%%