parse: Don't hold element's object lock while querying element pads' caps
[platform/upstream/gstreamer.git] / gst / parse / parse.l
index 9ef980b..50acf5c 100644 (file)
@@ -1,37 +1,65 @@
 %{
+#include "../gst_private.h"
+
 #include <math.h>
-#include <ctype.h>
 #include <string.h>
 
-#include "../gst_private.h"
+#include <glib/gprintf.h>
 
 #include "types.h"
 #include "../gstinfo.h"
 #include "../gsturi.h"
 #include "grammar.tab.h"
 
+#ifdef malloc
+#undef malloc
+#endif
+
+#ifdef free
+#undef free
+#endif
+
+#ifdef realloc
+#undef realloc
+#endif
+
+#define malloc g_malloc
+#define free g_free
+#define realloc g_realloc
+
+/* Override the default ECHO so as to avoid fortify warnings. Ignore the
+   embedded-NUL case for now. We know yytext is NUL-terminated. */
+#define ECHO g_fprintf(yyout, "%s", yytext)
+
 #ifdef G_HAVE_ISO_VARARGS
-#define PRINT(...) GST_CAT_DEBUG (GST_CAT_PIPELINE, "flex: "__VA_ARGS__)
+#define PRINT(...) GST_CAT_DEBUG (GST_CAT_PIPELINE, "flex: " __VA_ARGS__)
 #elif defined(G_HAVE_GNUC_VARARGS)
-#define PRINT(args...) GST_CAT_DEBUG (GST_CAT_PIPELINE, "flex: "##args)
+#define PRINT(args...) GST_CAT_DEBUG (GST_CAT_PIPELINE, "flex: " args)
 #else
-#define PRINT(args...)
+static inline void
+PRINT (const char *format, ...)
+{
+  va_list varargs;
+
+  va_start (varargs, format);
+  GST_CAT_LEVEL_LOG_valist (GST_CAT_PIPELINE, GST_LEVEL_DEBUG, NULL,
+    format, varargs);
+  va_end (varargs);
+}
 #endif
 
-#define YY_DECL int _gst_parse_yylex (YYSTYPE *lvalp)
 %}
 
-_operator [(){}.:!,;=]
-_identifier [[:alpha:]][[:alnum:]\-_%]*
+_operator [(){}.!:,;=]
+_identifier [[:alnum:]_][[:alnum:]\-_%:]*
 
 _char ("\\".)|([^[:space:]])
-_string {_char}+|("\""([^\"]|"\\\"")*"\"")|("'"([^']|"\\\"")*"'")
+_string {_char}+|("\""([^\"]|"\\\"")*"\"")|("'"([^']|"\\\'")*"'")
 
-_comma [[:space:]]*","[[:space:]]*
 _assign [[:space:]]*"="[[:space:]]*
 
 _protocol [[:alpha:]][[:alnum:]+-\.]*
-_url {_protocol}"://"{_string}|["."{_identifier}]?"/"{_string}
+_url ({_protocol}"://"{_string}|["."{_identifier}]?"/"{_string})|({_protocol}"://")
 
 /* we must do this here, because nearly everything matches a {_string} */ 
 _assignment {_identifier}{_assign}{_string}
@@ -42,37 +70,41 @@ _ref {_identifier}"."{_identifier}?
 _binref {_identifier}[[:space:]]*"."[[:space:]]*"("
 
 /* links */
-_mimechar ([[:alnum:]-])
-_mimetype ({_mimechar}+"/"{_mimechar}+)|("\""([^\"]|"\\\"")*"\"")|("'"([^']|"\\\"")*"'")
+_mimechar [[:alnum:]-]
+_mimetype {_mimechar}+"/"{_mimechar}+
 _capschar ("\\".)|([^\;!])
-_capsstring {_capschar}+|("\""([^\"]|"\\\"")*"\"")|("'"([^']|"\\\"")*"'")
+_capsstring {_capschar}+
 _caps {_mimetype}(","[^!]|{_capsstring})*
-_link ("!"[[:space:]]*{_caps}([[:space:]]*";"[[:space:]]*{_caps})*[[:space:]]*"!")|("!")
+_link ([!:][[:space:]]*{_caps}([[:space:]]*(";"[[:space:]]*{_caps})*[[:space:]]*)*[!:])|([!:])
 
 %x value
 %option noyywrap
 %option nounput
+%option reentrant
+%option bison-bridge
+%option never-interactive
+%option noinput
 %%
 
 {_assignment} {
     /* "=" */
-    PRINT ("ASSIGNMENT: %s\n", yytext);
-    lvalp->s = gst_parse_strdup (yytext);
+    PRINT ("ASSIGNMENT: %s", yytext);
+    yylval->ss = gst_parse_strdup (yytext);
     BEGIN (INITIAL);
     return ASSIGNMENT;
 }
 
 {_padref} {
     yytext++;
-    PRINT ("PADREF: %s\n", yytext);
-    lvalp->s = gst_parse_strdup (yytext);
+    PRINT ("PADREF: %s", yytext);
+    yylval->ss = gst_parse_strdup (yytext);
     BEGIN (INITIAL);
     return PADREF;
 }
 
 {_ref} {
-    PRINT ("REF: %s\n", yytext);
-    lvalp->s = gst_parse_strdup (yytext);
+    PRINT ("REF: %s", yytext);
+    yylval->ss = gst_parse_strdup (yytext);
     BEGIN (INITIAL);
     return REF;
 }
@@ -81,54 +113,63 @@ _link ("!"[[:space:]]*{_caps}([[:space:]]*";"[[:space:]]*{_caps})*[[:space:]]*"!
     gchar *pos = yytext;
     while (!g_ascii_isspace (*pos) && (*pos != '.')) pos++;
     *pos = '\0';
-    PRINT ("BINREF: %s\n", yytext);
-    lvalp->s = gst_parse_strdup (yytext);
+    PRINT ("BINREF: %s", yytext);
+    yylval->ss = gst_parse_strdup (yytext);
     BEGIN (INITIAL);
     return BINREF;
 }
 
 {_identifier} {
-    PRINT ("IDENTIFIER: %s\n", yytext);
-    lvalp->s = gst_parse_strdup (yytext);
+    PRINT ("IDENTIFIER: %s", yytext);
+    yylval->ss = gst_parse_strdup (yytext);
     BEGIN (INITIAL);
     return IDENTIFIER;
 }
 
 {_link} {
     gchar *c = yytext;
-    PRINT ("LINK: %s\n", yytext);
+    gchar op;
+    gboolean link_all;
+
+    PRINT ("LINK: %s", yytext);
+    /* First char is a link operator */
+    link_all = (*c == ':');
     c++;
     if (*c) {
       while (g_ascii_isspace (*c)) c++;
-      c = lvalp->s = gst_parse_strdup (c);
+      c = yylval->ss = gst_parse_strdup (c);
       while (*c) c++;
-      g_assert (*--c == '!');
+      /* Last non-space char is a link operator */
+      op = *--c;
+      if (op != '!' && op != ':')
+       g_assert_not_reached ();
+      if (op == ':')
+        link_all = TRUE;
+
+      /* Walk backward past whitespaces - what remains
+       * is a filter caps string, or empty */
       while (g_ascii_isspace (*--c));
       *++c = '\0';
     } else {
-      lvalp->s = NULL;
+      yylval->ss = NULL;
     }
     BEGIN (INITIAL);
-    return LINK;
+    return link_all ? LINK_ALL : LINK;
 }
 {_url} {
-  PRINT ("URL: %s\n", yytext);
-  if (gst_uri_is_valid (yytext)) {
-    lvalp->s = g_strdup (yytext);
-  } else {
-    lvalp->s = gst_uri_construct ("file", yytext);
-  }
-  gst_parse_unescape (lvalp->s);
+  PRINT ("URL: %s", yytext);
+  yylval->ss = g_strdup (yytext);
+  gst_parse_unescape (yylval->ss);
   BEGIN (INITIAL);
   return PARSE_URL;
 }
 
-{_operator} { PRINT ("OPERATOR: [%s]\n", yytext); return *yytext; }
+{_operator} { PRINT ("OPERATOR: [%s]", yytext); return *yytext; }
 
-[[:space:]]+ { PRINT ("SPACE: [%s]\n", yytext); }
+[[:space:]]+ { PRINT ("SPACE: [%s]", yytext); }
 
 . {
-    printf ("???: %s\n", yytext);
+    PRINT ("Invalid Lexer element: %s\n", yytext);
     return *yytext;
 }