%{
+#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 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
-#ifdef DEBUG
-# define PRINT(a...) printf(##a)
+/* 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
-#define PRINT(a...)
+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 CHAR(x) PRINT ("char: %c\n", *yytext); return *yytext;
%}
-_integer [[:digit:]]+
-_float [[:digit:]]+"."*[[:digit:]]*
-_number {_integer}|{_float}
-_boolean "true"|"false"|"TRUE"|"FALSE"
-_identifier [[:alpha:]][[:alnum:]\-_]*
-_string ([^[:space:]\"]|"\\\"")+|("\""([^\"]|"\\\"")*"\"")
+_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));
- BEGIN (INITIAL);
- return INTEGER;
- }
-
- {_float} {
- PRINT ("A float: %s (%g)\n", yytext, atof (yytext));
- BEGIN (INITIAL);
- return FLOAT;
- }
-
- {_boolean} {
- PRINT ("A boolean: %s (%d)\n", yytext, tolower (*yytext) == 't' ? 1 : 0);
- BEGIN (INITIAL);
- return BOOLEAN;
- }
-
- {_string} {
- if (*yytext == '"') {
- yytext++;
- *(yytext + strlen (yytext) - 1) = '\0';
- }
- PRINT ("A string: %s\n", yytext);
- BEGIN (INITIAL);
- return STRING;
- }
-
- [[:space:]]+ { /* PRINT ("space: [%s]\n", yytext); */ }
-
- . {
- PRINT ("unknown: %s\n", yytext);
- }
+{_assignment} {
+ /* "=" */
+ PRINT ("ASSIGNMENT: %s", yytext);
+ yylval->ss = gst_parse_strdup (yytext);
+ BEGIN (INITIAL);
+ return ASSIGNMENT;
+}
+
+{_padref} {
+ yytext++;
+ PRINT ("PADREF: %s", yytext);
+ yylval->ss = gst_parse_strdup (yytext);
+ BEGIN (INITIAL);
+ return PADREF;
+}
+
+{_ref} {
+ PRINT ("REF: %s", yytext);
+ yylval->ss = gst_parse_strdup (yytext);
+ BEGIN (INITIAL);
+ return REF;
+}
+
+{_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);
+ 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;
}