element: Enforce that elements created by gst_element_factory_create/make() are floating
[platform/upstream/gstreamer.git] / gst / parse / parse.l
index 3b21d3e..50acf5c 100644 (file)
 %{
+#include "../gst_private.h"
+
 #include <math.h>
-#include <ctype.h>
 #include <string.h>
+
+#include <glib/gprintf.h>
+
 #include "types.h"
-#include <grammar.tab.h>
+#include "../gstinfo.h"
+#include "../gsturi.h"
+#include "grammar.tab.h"
 
-#ifdef DEBUG
-# define PRINT(a...) printf(##a)
-#else
-#define PRINT(a...)
+#ifdef malloc
+#undef malloc
+#endif
+
+#ifdef free
+#undef free
+#endif
+
+#ifdef realloc
+#undef realloc
 #endif
 
-#define CHAR(x) PRINT ("char: %c\n", *yytext); return *yytext;
+#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__)
+#elif defined(G_HAVE_GNUC_VARARGS)
+#define PRINT(args...) GST_CAT_DEBUG (GST_CAT_PIPELINE, "flex: " args)
+#else
+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)
-#define YY_NO_UNPUT
 %}
 
-_integer [-+]?[[:digit:]]+
-_double [-+]?[[:digit:]]+"."*[[:digit:]]*
-_number {_integer}|{_double}
-_boolean "true"|"false"|"TRUE"|"FALSE"
-_identifier [[:alpha:]][[:alnum:]\-_%:]*
-_lconnection ({_identifier}\.)?{_identifier}!
-_rconnection !({_identifier}\.)?{_identifier}
-_bconnection ({_identifier}\.)?{_identifier}!({_identifier}\.)?{_identifier}
-_char ([^[:space:]])|("\\".)
-_string {_char}+|("\""([^\"]|"\\\"")*"\"")
+_operator [(){}.!:,;=]
+_identifier [[:alnum:]_][[:alnum:]\-_%:]*
+
+_char ("\\".)|([^[:space:]])
+_string {_char}+|("\""([^\"]|"\\\"")*"\"")|("'"([^']|"\\\'")*"'")
+
+_assign [[:space:]]*"="[[:space:]]*
+
+_protocol [[:alpha:]][[:alnum:]+-\.]*
+_url ({_protocol}"://"{_string}|["."{_identifier}]?"/"{_string})|({_protocol}"://")
+
+/* we must do this here, because nearly everything matches a {_string} */ 
+_assignment {_identifier}{_assign}{_string}
+
+/* get pad/element references and stuff with dots right */
+_padref "."{_identifier}
+_ref {_identifier}"."{_identifier}?
+_binref {_identifier}[[:space:]]*"."[[:space:]]*"("
+
+/* links */
+_mimechar [[:alnum:]-]
+_mimetype {_mimechar}+"/"{_mimechar}+
+_capschar ("\\".)|([^\;!])
+_capsstring {_capschar}+
+_caps {_mimetype}(","[^!]|{_capsstring})*
+_link ([!:][[:space:]]*{_caps}([[:space:]]*(";"[[:space:]]*{_caps})*[[:space:]]*)*[!:])|([!:])
 
 %x value
 %option noyywrap
+%option nounput
+%option reentrant
+%option bison-bridge
+%option never-interactive
+%option noinput
 %%
 
-<value>{
-    {_integer} {
-        PRINT ("An integer: %s (%d)\n", yytext,
-               atoi (yytext));
-        lvalp->v = g_new0 (GValue, 1);
-        g_value_init (lvalp->v, G_TYPE_INT);
-        g_value_set_int (lvalp->v, atoi (yytext));
-        BEGIN (INITIAL);
-        return VALUE;
-    }
-    
-    {_double}  {
-        PRINT ("A double: %s (%g)\n", yytext, atof (yytext));
-        lvalp->v = g_new0 (GValue, 1);
-        g_value_init (lvalp->v, G_TYPE_DOUBLE);
-        g_value_set_double (lvalp->v, atof (yytext));
-        BEGIN (INITIAL);
-        return VALUE;
-    }
-    
-    {_boolean} {
-        PRINT ("A boolean: %s (%d)\n", yytext, tolower (*yytext) == 't' ? 1 : 0);
-        lvalp->v = g_new0 (GValue, 1);
-        g_value_init (lvalp->v, G_TYPE_BOOLEAN);
-        g_value_set_boolean (lvalp->v, tolower (*yytext) == 't' ? TRUE : FALSE);
-        BEGIN (INITIAL);
-        return VALUE;
-    }
-    
-    {_string} {
-        if (*yytext == '"') {
-            yytext++;
-            *(yytext + strlen (yytext) - 1) = '\0';
-        }
-        _gst_parse_unescape (yytext);
-        PRINT ("A string: \"%s\"\n", yytext);
-        lvalp->v = g_new0 (GValue, 1);
-        g_value_init (lvalp->v, G_TYPE_STRING);
-        g_value_set_string (lvalp->v, yytext);
-        BEGIN (INITIAL);
-        return VALUE;
-    }
-    
-    [[:space:]]+ { /* PRINT ("space: [%s]\n", yytext); */ }
+{_assignment} {
+    /* "=" */
+    PRINT ("ASSIGNMENT: %s", yytext);
+    yylval->ss = gst_parse_strdup (yytext);
+    BEGIN (INITIAL);
+    return ASSIGNMENT;
 }
 
-{_lconnection} {
-    gchar *d1, *q;
-    lvalp->c = g_new0 (connection_t, 1);
-    PRINT ("An connection: %s\n", yytext);
-    q = strchr (yytext, '!');
-    d1 = strchr (yytext, '.');
-    if (d1) {
-        lvalp->c->src_name = g_strndup (yytext, d1 - yytext);
-        lvalp->c->src_pads = g_list_append (lvalp->c->src_pads, g_strndup (d1 + 1, q - d1 - 1));
-    } else {
-        lvalp->c->src_pads = g_list_append (lvalp->c->src_pads, g_strndup (yytext, q - yytext));
-    }
-    
-    return CONNECTION;
+{_padref} {
+    yytext++;
+    PRINT ("PADREF: %s", yytext);
+    yylval->ss = gst_parse_strdup (yytext);
+    BEGIN (INITIAL);
+    return PADREF;
 }
 
-{_rconnection} {
-    gchar *d2;
-    lvalp->c = g_new0 (connection_t, 1);
-    PRINT ("An rconnection: %s\n", yytext);
-    d2 = strchr (yytext, '.');
-    if (d2) {
-        lvalp->c->sink_name = g_strndup (yytext + 1, d2 - yytext - 1);
-        lvalp->c->sink_pads = g_list_append (lvalp->c->sink_pads, g_strdup (d2 + 1));
-    } else {
-        lvalp->c->sink_pads = g_list_append (lvalp->c->sink_pads, g_strdup (yytext + 1));
-    }
-
-    return CONNECTION;
+{_ref} {
+    PRINT ("REF: %s", yytext);
+    yylval->ss = gst_parse_strdup (yytext);
+    BEGIN (INITIAL);
+    return REF;
 }
 
-{_bconnection} {
-    gchar *d1, *d2, *q;
-    lvalp->c = g_new0 (connection_t, 1);
-    PRINT ("A bconnection: %s\n", yytext);
-    q = strchr (yytext, '!');
-    d1 = strchr (yytext, '.');
-    d2 = strchr (q, '.');
-    if (d1 && d1 < q) {
-        lvalp->c->src_name = g_strndup (yytext, d1 - yytext);
-        lvalp->c->src_pads = g_list_append (lvalp->c->src_pads, g_strndup (d1 + 1, q - d1 - 1));
-    } else {
-        lvalp->c->src_pads = g_list_append (lvalp->c->src_pads, g_strndup (yytext, q - yytext));
-    }
-    
-    if (d2) {
-        lvalp->c->sink_name = g_strndup (q + 1, d2 - q - 1);
-        lvalp->c->sink_pads = g_list_append (lvalp->c->sink_pads, g_strdup (d2 + 1));
-    } else {
-        lvalp->c->sink_pads = g_list_append (lvalp->c->sink_pads, g_strdup (q + 1));
-    }
-
-    return BCONNECTION;
+{_binref} {
+    gchar *pos = yytext;
+    while (!g_ascii_isspace (*pos) && (*pos != '.')) pos++;
+    *pos = '\0';
+    PRINT ("BINREF: %s", yytext);
+    yylval->ss = gst_parse_strdup (yytext);
+    BEGIN (INITIAL);
+    return BINREF;
 }
 
 {_identifier} {
-    PRINT ("An identifier: %s\n", yytext);
-    lvalp->s = g_strdup (yytext);
+    PRINT ("IDENTIFIER: %s", yytext);
+    yylval->ss = gst_parse_strdup (yytext);
+    BEGIN (INITIAL);
     return IDENTIFIER;
 }
 
-"=" { BEGIN (value); CHAR ('='); }
-"@" { CHAR ('@'); }
-"." { CHAR ('.'); }
-"," { CHAR (','); }
-"{" { CHAR ('{'); }
-"}" { CHAR ('}'); }
-"[" { CHAR ('['); }
-"]" { CHAR (']'); }
-"(" { CHAR ('('); }
-")" { CHAR (')'); }
-"!" { CHAR ('!'); }
-"+" { CHAR ('+'); }
-
-[[:space:]]+ { PRINT ("space: [%s]\n", yytext); }
+{_link} {
+    gchar *c = 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 = yylval->ss = gst_parse_strdup (c);
+      while (*c) 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 {
+      yylval->ss = NULL;
+    }
+    BEGIN (INITIAL);
+    return link_all ? LINK_ALL : LINK;
+}
+{_url} {
+  PRINT ("URL: %s", yytext);
+  yylval->ss = g_strdup (yytext);
+  gst_parse_unescape (yylval->ss);
+  BEGIN (INITIAL);
+  return PARSE_URL;
+}
+
+{_operator} { PRINT ("OPERATOR: [%s]", yytext); return *yytext; }
+
+[[:space:]]+ { PRINT ("SPACE: [%s]", yytext); }
 
 . {
-    printf ("unknown: %s\n", yytext);
+    PRINT ("Invalid Lexer element: %s\n", yytext);
     return *yytext;
 }