gst/parse/: Make the parser reentrant and recursively callable. This requires flex >= 2.5.31, for older versions preg...

Original commit message from CVS:
Patch by: Marc-Andre Lureau <marcandre dot lureau at gmail dot com>
* gst/parse/Makefile.am:
* gst/parse/grammar.y:
* gst/parse/parse.l:
Make the parser reentrant and recursively callable. This requires flex
>= 2.5.31, for older versions pregenerated sources are used as we
can't bump the build dependency. Finally fixes #349180.
* gst/gstparse.c: (gst_parse_launch):
Drop the HAVE_MT_SAVE_FLEX #ifdefs as we always use a new enough flex
now anyway.
* docs/gst/Makefile.am:
* docs/gst/Makefile.am:
* gst/parse/grammar.tab.pre.c: (__gst_parse_strdup),
(__gst_parse_strfree), (__gst_parse_link_new),
(__gst_parse_link_free), (__gst_parse_chain_new),
(__gst_parse_chain_free), (SET_ERROR), (YYPRINTF),
(gst_parse_element_set), (gst_parse_free_link),
(gst_parse_found_pad), (gst_parse_perform_delayed_link),
(gst_parse_perform_link), (yytnamerr), (yysyntax_error), (yyerror),
(_gst_parse_launch):
* gst/parse/grammar.tab.pre.h:
* gst/parse/lex._gst_parse_yy.pre.c: (PRINT), (yy_get_next_buffer),
(yy_get_previous_state), (yy_try_NUL_trans), (input),
(_gst_parse_yyrestart), (_gst_parse_yy_switch_to_buffer),
(_gst_parse_yy_load_buffer_state), (_gst_parse_yy_create_buffer),
(_gst_parse_yy_delete_buffer), (_gst_parse_yy_init_buffer),
(_gst_parse_yy_flush_buffer), (_gst_parse_yypush_buffer_state),
(_gst_parse_yypop_buffer_state),
(_gst_parse_yyensure_buffer_stack), (_gst_parse_yy_scan_buffer),
(_gst_parse_yy_scan_string), (_gst_parse_yy_scan_bytes),
(yy_fatal_error), (_gst_parse_yyget_extra),
(_gst_parse_yyget_lineno), (_gst_parse_yyget_column),
(_gst_parse_yyget_in), (_gst_parse_yyget_out),
(_gst_parse_yyget_leng), (_gst_parse_yyget_text),
(_gst_parse_yyset_extra), (_gst_parse_yyset_lineno),
(_gst_parse_yyset_column), (_gst_parse_yyset_in),
(_gst_parse_yyset_out), (_gst_parse_yyget_debug),
(_gst_parse_yyset_debug), (_gst_parse_yyget_lval),
(_gst_parse_yyset_lval), (_gst_parse_yylex_init),
(yy_init_globals), (_gst_parse_yylex_destroy), (yy_flex_strncpy),
(yy_flex_strlen), (_gst_parse_yyalloc), (_gst_parse_yyrealloc),
(_gst_parse_yyfree):
If the installed flex version is too old use pre-generated parser
sources. These pre-generated parser sources are always updated when
the actual flex/bison sources change but require everybody who wants
to change something in the parser to have flex >= 2.5.31 installed.
This commit is contained in:
Marc-Andre Lureau 2007-04-18 12:34:51 +00:00 committed by Sebastian Dröge
parent fdbd97497f
commit 7a3a27d0c1
10 changed files with 5319 additions and 60 deletions

View file

@ -1,3 +1,54 @@
2007-04-18 Sebastian Dröge <slomo@circular-chaos.org>
Patch by: Marc-Andre Lureau <marcandre dot lureau at gmail dot com>
* gst/parse/Makefile.am:
* gst/parse/grammar.y:
* gst/parse/parse.l:
Make the parser reentrant and recursively callable. This requires flex
>= 2.5.31, for older versions pregenerated sources are used as we
can't bump the build dependency. Finally fixes #349180.
* gst/gstparse.c: (gst_parse_launch):
Drop the HAVE_MT_SAVE_FLEX #ifdefs as we always use a new enough flex
now anyway.
* docs/gst/Makefile.am:
* docs/gst/Makefile.am:
* gst/parse/grammar.tab.pre.c: (__gst_parse_strdup),
(__gst_parse_strfree), (__gst_parse_link_new),
(__gst_parse_link_free), (__gst_parse_chain_new),
(__gst_parse_chain_free), (SET_ERROR), (YYPRINTF),
(gst_parse_element_set), (gst_parse_free_link),
(gst_parse_found_pad), (gst_parse_perform_delayed_link),
(gst_parse_perform_link), (yytnamerr), (yysyntax_error), (yyerror),
(_gst_parse_launch):
* gst/parse/grammar.tab.pre.h:
* gst/parse/lex._gst_parse_yy.pre.c: (PRINT), (yy_get_next_buffer),
(yy_get_previous_state), (yy_try_NUL_trans), (input),
(_gst_parse_yyrestart), (_gst_parse_yy_switch_to_buffer),
(_gst_parse_yy_load_buffer_state), (_gst_parse_yy_create_buffer),
(_gst_parse_yy_delete_buffer), (_gst_parse_yy_init_buffer),
(_gst_parse_yy_flush_buffer), (_gst_parse_yypush_buffer_state),
(_gst_parse_yypop_buffer_state),
(_gst_parse_yyensure_buffer_stack), (_gst_parse_yy_scan_buffer),
(_gst_parse_yy_scan_string), (_gst_parse_yy_scan_bytes),
(yy_fatal_error), (_gst_parse_yyget_extra),
(_gst_parse_yyget_lineno), (_gst_parse_yyget_column),
(_gst_parse_yyget_in), (_gst_parse_yyget_out),
(_gst_parse_yyget_leng), (_gst_parse_yyget_text),
(_gst_parse_yyset_extra), (_gst_parse_yyset_lineno),
(_gst_parse_yyset_column), (_gst_parse_yyset_in),
(_gst_parse_yyset_out), (_gst_parse_yyget_debug),
(_gst_parse_yyset_debug), (_gst_parse_yyget_lval),
(_gst_parse_yyset_lval), (_gst_parse_yylex_init),
(yy_init_globals), (_gst_parse_yylex_destroy), (yy_flex_strncpy),
(yy_flex_strlen), (_gst_parse_yyalloc), (_gst_parse_yyrealloc),
(_gst_parse_yyfree):
If the installed flex version is too old use pre-generated parser
sources. These pre-generated parser sources are always updated when
the actual flex/bison sources change but require everybody who wants
to change something in the parser to have flex >= 2.5.31 installed.
2007-04-18 Stefan Kost <ensonic@users.sf.net>
* common/m4/gst-gettext.m4:

2
common

@ -1 +1 @@
Subproject commit 380281f0da9caa065cfe99a458b3538cc3f5d71a
Subproject commit dae6fa1f592c9231820c2135b8b1b3c2b0875ef6

View file

@ -73,6 +73,7 @@ IGNORE_HFILES= \
types.h \
glib-compat.h \
grammar.tab.h \
grammar.tab.pre.h \
gstmarshal.h \
gstaggregator.h \
gstbufferstore.h \

View file

@ -36,12 +36,6 @@
#include "gstparse.h"
#include "gstinfo.h"
#ifndef HAVE_MT_SAVE_FLEX
/* the need for the mutex will go away with flex 2.5.6 */
static gboolean flex_busy = FALSE;
static GStaticRecMutex flex_lock = G_STATIC_REC_MUTEX_INIT;
#endif
extern GstElement *_gst_parse_launch (const gchar *, GError **);
/**
@ -149,30 +143,9 @@ gst_parse_launch (const gchar * pipeline_description, GError ** error)
GST_CAT_INFO (GST_CAT_PIPELINE, "parsing pipeline description %s",
pipeline_description);
#ifndef HAVE_MT_SAVE_FLEX
g_static_rec_mutex_lock (&flex_lock);
if (flex_busy)
goto recursive_call;
flex_busy = TRUE;
#endif
element = _gst_parse_launch (pipeline_description, error);
#ifndef HAVE_MT_SAVE_FLEX
flex_busy = FALSE;
g_static_rec_mutex_unlock (&flex_lock);
#endif
return element;
/* ERRORS */
#ifndef HAVE_MT_SAVE_FLEX
recursive_call:
{
GST_WARNING ("calls to gst_parse_launch() cannot be nested");
g_static_rec_mutex_unlock (&flex_lock);
g_warning ("calls to gst_parse_launch() cannot be nested");
return NULL;
}
#endif
}

View file

@ -2,7 +2,13 @@
noinst_LTLIBRARIES = libgstparse.la
CLEANFILES = grammar.tab.h grammar.output
EXTRA_DIST = grammar.y parse.l types.h
EXTRA_DIST = \
grammar.y \
parse.l \
types.h \
grammar.tab.pre.c \
grammar.tab.pre.h \
lex._gst_parse_yy.pre.c
# uncomment these lines to dist the generated sources
#BUILT_SOURCES = grammar.tab.h grammar.tab.c lex._gst_parse_yy.c
@ -17,8 +23,10 @@ libgstparse_la_LIBADD = $(GST_ALL_LIBS)
noinst_HEADERS = grammar.tab.h
grammar.tab.c grammar.tab.h: grammar.y
$(BISON_PATH) -d -v -p_gst_parse__yy $(srcdir)/grammar.y -o grammar.tab.c && \
all: grammar.tab.pre.c grammar.tab.pre.h lex._gst_parse_yy.pre.c
grammar.tab.pre.c grammar.tab.pre.h: grammar.y
$(BISON_PATH) -d -v -p_gst_parse_yy $(srcdir)/grammar.y -o grammar.tab.c && \
mv grammar.tab.c grammar.tab_tmp.c && \
echo '#ifdef HAVE_CONFIG_H' > grammar.tab_tmp2.c && \
echo '#include <config.h>' >> grammar.tab_tmp2.c && \
@ -26,7 +34,37 @@ grammar.tab.c grammar.tab.h: grammar.y
cat grammar.tab_tmp.c >> grammar.tab_tmp2.c && \
rm grammar.tab_tmp.c && \
mv grammar.tab_tmp2.c grammar.tab.c
cp grammar.tab.c grammar.tab.pre.c
cp grammar.tab.h grammar.tab.pre.h
lex._gst_parse_yy.pre.c: parse.l grammar.tab.pre.h
$(FLEX_PATH) -P_gst_parse_yy $^ && \
mv lex._gst_parse_yy.c lex._gst_parse_yy_tmp.c && \
echo '#ifdef HAVE_CONFIG_H' > lex._gst_parse_yy_tmp2.c && \
echo '#include <config.h>' >> lex._gst_parse_yy_tmp2.c && \
echo '#endif' >> lex._gst_parse_yy_tmp2.c && \
cat lex._gst_parse_yy_tmp.c >> lex._gst_parse_yy_tmp2.c && \
rm lex._gst_parse_yy_tmp.c && \
mv lex._gst_parse_yy_tmp2.c lex._gst_parse_yy.c
cp lex._gst_parse_yy.c lex._gst_parse_yy.pre.c
if GENERATE_PARSER
grammar.tab.c grammar.tab.h: grammar.y
$(BISON_PATH) -d -v -p_gst_parse_yy $(srcdir)/grammar.y -o grammar.tab.c && \
mv grammar.tab.c grammar.tab_tmp.c && \
echo '#ifdef HAVE_CONFIG_H' > grammar.tab_tmp2.c && \
echo '#include <config.h>' >> grammar.tab_tmp2.c && \
echo '#endif' >> grammar.tab_tmp2.c && \
cat grammar.tab_tmp.c >> grammar.tab_tmp2.c && \
rm grammar.tab_tmp.c && \
mv grammar.tab_tmp2.c grammar.tab.c
else
grammar.tab.c grammar.tab.h: grammar.tab.pre.c grammar.tab.pre.h
cp $(srcdir)/grammar.tab.pre.h grammar.tab.h
cp $(srcdir)/grammar.tab.pre.c grammar.tab.c
endif
if GENERATE_PARSER
lex._gst_parse_yy.c: parse.l grammar.tab.h
$(FLEX_PATH) -P_gst_parse_yy $^ && \
mv lex._gst_parse_yy.c lex._gst_parse_yy_tmp.c && \
@ -36,6 +74,10 @@ lex._gst_parse_yy.c: parse.l grammar.tab.h
cat lex._gst_parse_yy_tmp.c >> lex._gst_parse_yy_tmp2.c && \
rm lex._gst_parse_yy_tmp.c && \
mv lex._gst_parse_yy_tmp2.c lex._gst_parse_yy.c
else
lex._gst_parse_yy.c: lex._gst_parse_yy.pre.c
cp $(srcdir)/lex._gst_parse_yy.pre.c lex._gst_parse_yy.c
endif
.NOTPARALLEL:

2642
gst/parse/grammar.tab.pre.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,83 @@
/* A Bison parser, made by GNU Bison 2.3. */
/* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
PARSE_URL = 258,
IDENTIFIER = 259,
BINREF = 260,
PADREF = 261,
REF = 262,
ASSIGNMENT = 263,
LINK = 264
};
#endif
/* Tokens. */
#define PARSE_URL 258
#define IDENTIFIER 259
#define BINREF 260
#define PADREF 261
#define REF 262
#define ASSIGNMENT 263
#define LINK 264
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
#line 468 "./grammar.y"
{
gchar *s;
chain_t *c;
link_t *l;
GstElement *e;
GSList *p;
graph_t *g;
}
/* Line 1489 of yacc.c. */
#line 76 "grammar.tab.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif

View file

@ -24,7 +24,17 @@
*/
#define YYERROR_VERBOSE 1
#define YYPARSE_PARAM graph
#define YYLEX_PARAM scanner
typedef void* yyscan_t;
int _gst_parse_yylex (void * yylval_param , yyscan_t yyscanner);
int _gst_parse_yylex_init (yyscan_t scanner);
int _gst_parse_yylex_destroy (yyscan_t scanner);
struct yy_buffer_state * _gst_parse_yy_scan_string (char* , yyscan_t);
void _gst_parse_yypush_buffer_state (void * new_buffer ,yyscan_t yyscanner );
void _gst_parse_yypop_buffer_state (yyscan_t yyscanner );
#ifdef __GST_PARSE_TRACE
static guint __strings;
@ -455,8 +465,7 @@ error:
}
static int yylex (void *lvalp);
static int yyerror (const char *s);
static int yyerror (void *scanner, graph_t *graph, const char *s);
%}
%union {
@ -487,7 +496,9 @@ static int yyerror (const char *s);
%right '.'
%left '!' '='
%pure_parser
%parse-param { void *scanner }
%parse-param { graph_t *graph }
%pure-parser
%start graph
%%
@ -712,23 +723,16 @@ graph: /* NOP */ { SET_ERROR (((graph_t *) graph)->error, GST_PARSE_ERRO
%%
extern FILE *_gst_parse_yyin;
int _gst_parse_yylex (YYSTYPE *lvalp);
static int yylex (void *lvalp) {
return _gst_parse_yylex ((YYSTYPE*) lvalp);
}
static int
yyerror (const char *s)
yyerror (void *scanner, graph_t *graph, const char *s)
{
/* FIXME: This should go into the GError somehow, but how? */
GST_WARNING ("Error during parsing: %s", s);
return -1;
}
struct yy_buffer_state * _gst_parse_yy_scan_string (char*);
void _gst_parse_yy_delete_buffer (struct yy_buffer_state *);
GstElement *
_gst_parse_launch (const gchar *str, GError **error)
{
@ -737,8 +741,8 @@ _gst_parse_launch (const gchar *str, GError **error)
GSList *walk;
GstBin *bin = NULL;
GstElement *ret;
struct yy_buffer_state *buf;
yyscan_t scanner;
g_return_val_if_fail (str != NULL, NULL);
g.chain = NULL;
@ -751,23 +755,24 @@ _gst_parse_launch (const gchar *str, GError **error)
#endif /* __GST_PARSE_TRACE */
dstr = g_strdup (str);
buf = _gst_parse_yy_scan_string (dstr);
_gst_parse_yylex_init (&scanner);
_gst_parse_yy_scan_string (dstr, scanner);
#ifndef YYDEBUG
yydebug = 1;
#endif
if (yyparse (&g) != 0) {
if (yyparse (scanner, &g) != 0) {
SET_ERROR (error, GST_PARSE_ERROR_SYNTAX,
"Unrecoverable syntax error while parsing pipeline %s", str);
_gst_parse_yy_delete_buffer (buf);
_gst_parse_yylex_destroy (scanner);
g_free (dstr);
goto error1;
}
_gst_parse_yylex_destroy (scanner);
g_free (dstr);
_gst_parse_yy_delete_buffer (buf);
GST_CAT_DEBUG (GST_CAT_PIPELINE, "got %u elements and %u links",
g.chain ? g_slist_length (g.chain->elements) : 0,

File diff suppressed because it is too large Load diff

View file

@ -32,7 +32,6 @@ PRINT (const char *format, ...)
}
#endif
#define YY_DECL int _gst_parse_yylex (YYSTYPE *lvalp)
%}
_operator [(){}.!,;=]
@ -65,12 +64,14 @@ _link ("!"[[:space:]]*{_caps}([[:space:]]*(";"[[:space:]]*{_caps})*[[:space:]]*)
%x value
%option noyywrap
%option nounput
%option reentrant
%option bison-bridge
%%
{_assignment} {
/* "=" */
PRINT ("ASSIGNMENT: %s", yytext);
lvalp->s = gst_parse_strdup (yytext);
yylval->s = gst_parse_strdup (yytext);
BEGIN (INITIAL);
return ASSIGNMENT;
}
@ -78,14 +79,14 @@ _link ("!"[[:space:]]*{_caps}([[:space:]]*(";"[[:space:]]*{_caps})*[[:space:]]*)
{_padref} {
yytext++;
PRINT ("PADREF: %s", yytext);
lvalp->s = gst_parse_strdup (yytext);
yylval->s = gst_parse_strdup (yytext);
BEGIN (INITIAL);
return PADREF;
}
{_ref} {
PRINT ("REF: %s", yytext);
lvalp->s = gst_parse_strdup (yytext);
yylval->s = gst_parse_strdup (yytext);
BEGIN (INITIAL);
return REF;
}
@ -95,14 +96,14 @@ _link ("!"[[:space:]]*{_caps}([[:space:]]*(";"[[:space:]]*{_caps})*[[:space:]]*)
while (!g_ascii_isspace (*pos) && (*pos != '.')) pos++;
*pos = '\0';
PRINT ("BINREF: %s", yytext);
lvalp->s = gst_parse_strdup (yytext);
yylval->s = gst_parse_strdup (yytext);
BEGIN (INITIAL);
return BINREF;
}
{_identifier} {
PRINT ("IDENTIFIER: %s", yytext);
lvalp->s = gst_parse_strdup (yytext);
yylval->s = gst_parse_strdup (yytext);
BEGIN (INITIAL);
return IDENTIFIER;
}
@ -113,22 +114,22 @@ _link ("!"[[:space:]]*{_caps}([[:space:]]*(";"[[:space:]]*{_caps})*[[:space:]]*)
c++;
if (*c) {
while (g_ascii_isspace (*c)) c++;
c = lvalp->s = gst_parse_strdup (c);
c = yylval->s = gst_parse_strdup (c);
while (*c) c++;
if (*--c != '!')
g_assert_not_reached ();
while (g_ascii_isspace (*--c));
*++c = '\0';
} else {
lvalp->s = NULL;
yylval->s = NULL;
}
BEGIN (INITIAL);
return LINK;
}
{_url} {
PRINT ("URL: %s", yytext);
lvalp->s = g_strdup (yytext);
gst_parse_unescape (lvalp->s);
yylval->s = g_strdup (yytext);
gst_parse_unescape (yylval->s);
BEGIN (INITIAL);
return PARSE_URL;
}