use contents of GST_REGISTRY variable if --gst-registry is not set
[platform/upstream/gstreamer.git] / gst / parse / grammar.y
1 %{
2 #include <glib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include "../gstparse.h"
6 #include "types.h"
7
8 #define YYDEBUG 1
9 #define YYERROR_VERBOSE 1
10 #define YYPARSE_PARAM pgraph
11
12 static int yylex (void *lvalp);
13 static int yyerror (const char *s);
14 %}
15
16 %union {
17     gchar *s;
18     GValue *v;
19     graph_t *g;
20     connection_t *c;
21     property_t *p;
22     element_t *e;
23 }
24
25 %token <s> IDENTIFIER
26 %token <c> CONNECTION BCONNECTION
27 %token <v> VALUE
28
29 %type <s> id
30 %type <g> graph bin
31 %type <e> element
32 %type <p> property_value value
33 %type <c> connection rconnection
34
35 %left '{' '}' '(' ')'
36 %left '!' '='
37 %left ','
38 %left '.'
39
40 %pure_parser
41
42 %start graph
43 %%
44
45 id:     IDENTIFIER
46         ;
47
48 value:          VALUE                { $$ = g_new0 (property_t, 1); $$->value = $1; }
49         ;
50
51 property_value: id '=' value         { $$ = $3; $$->name = $1; }
52         ;
53
54 element:        id                   { static int i = 0; $$ = g_new0 (element_t, 1);
55                                        $$->type = $1; $$->index = ++i; }
56         ;
57
58 graph:          /* empty */          { $$ = g_new0 (graph_t, 1); *((graph_t**) pgraph) = $$; }
59         |       graph element        { GList *l;
60                                        $$ = $1; l = $$->connections_pending;
61                                        $$->elements = g_list_append ($$->elements, $2);
62                                        $$->current = $2;
63                                        if (!$$->first)
64                                            $$->first = $$->current;
65                                        while (l) {
66                                            ((connection_t*) l->data)->sink_index = $$->current->index;
67                                            l = g_list_next (l);
68                                        }
69                                        if ($$->connections_pending) {
70                                            g_list_free ($$->connections_pending);
71                                            $$->connections_pending = NULL;
72                                        }
73                                      }
74         |       graph bin            { GList *l; $$ = $1; l = $$->connections_pending;
75                                        *((graph_t**) pgraph) = $$;
76                                        $$->bins = g_list_append ($$->bins, $2);
77                                        $2->parent = $$;
78                                        $$->current = $2->first;
79                                        if (!$$->first)
80                                            $$->first = $$->current;
81                                        while (l) {
82                                            ((connection_t*) l->data)->sink_index = $$->current->index;
83                                            l = g_list_next (l);
84                                        }
85                                        if ($$->connections_pending) {
86                                            g_list_free ($$->connections_pending);
87                                            $$->connections_pending = NULL;
88                                        }
89                                        $$->current = $2->current;
90                                      }
91         |       graph connection     { $$ = $1;
92                                        $$->connections = g_list_append ($$->connections, $2);
93                                        $2->src_index = $$->current->index;
94                                        if (!$2->sink_name)
95                                            $$->connections_pending = g_list_append ($$->connections_pending, $2);
96                                      }
97         |       graph property_value { $$ = $1;
98                                        if (!$$->current) {
99                                            fprintf (stderr, "error: property value assignments must be preceded by an element definition\n");
100                                            YYABORT;
101                                        }
102                                        $$->current->property_values = g_list_append ($$->current->property_values,
103                                                                                      $2);
104                                      }
105         ;
106
107 bin:            '{' graph '}'        { $$ = $2; $$->current_bin_type = "thread"; }
108         |       id '.' '(' graph ')' { $$ = $4; $$->current_bin_type = $1; }
109         ;
110
111 connection:     CONNECTION
112         |       rconnection
113         ;
114
115 rconnection:   '!'                   { $$ = g_new0 (connection_t, 1); }
116         |       BCONNECTION          { $$ = $1; }
117         |       id ',' rconnection ',' id 
118                                      { $$ = $3;
119                                        $$->src_pads = g_list_prepend ($$->src_pads, $1);
120                                        $$->sink_pads = g_list_append ($$->sink_pads, $5);
121                                      }
122         ;
123
124 %%
125
126 extern FILE *yyin;
127 int _gst_parse_yylex (YYSTYPE *lvalp);
128
129 static int yylex (void *lvalp) {
130     return _gst_parse_yylex ((YYSTYPE*) lvalp);
131 }
132
133 static int
134 yyerror (const char *s)
135 {
136   fprintf (stderr, "error: %s\n", s);
137   return -1;
138 }
139
140 int yy_scan_string (char*);
141
142 graph_t * _gst_parse_launch (const gchar *str, GError **error)
143 {
144     graph_t *g = NULL;
145     gchar *dstr;
146     
147     g_return_val_if_fail (str != NULL, NULL);
148
149     dstr = g_strdup (str);
150     yy_scan_string (dstr);
151
152 #ifdef DEBUG
153     yydebug = 1;
154 #endif
155
156     if (yyparse (&g) != 0) {
157         g_set_error (error,
158                      GST_PARSE_ERROR,
159                      GST_PARSE_ERROR_SYNTAX,
160                      "Invalid syntax");
161         g_free (dstr);
162         return NULL;
163     }
164     
165     g_assert (g != NULL);
166
167     g_free (dstr);
168
169     /* if the toplevel only contains one bin, make that bin top-level */
170     if (g->elements == NULL && g->bins && g->bins->next == NULL) {
171         g = (graph_t*)g->bins->data;
172         g_free (g->parent);
173         g->parent = NULL;
174     }
175
176     return g;
177 }