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