1 #ifdef HAVE_CONFIG_H
2 #include <config.h>
3 #endif
4 /* A Bison parser, made by GNU Bison 1.875d. */
6 /* Skeleton parser for Yacc-like parsing with Bison,
7 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
24 /* As a special exception, when this file is copied by Bison into a
25 Bison output file, you may use that output file without restriction.
26 This special exception was added by the Free Software Foundation
27 in version 1.24 of Bison. */
29 /* Written by Richard Stallman by simplifying the original so called
30 ``semantic'' parser. */
32 /* All symbols defined below should begin with yy or YY, to avoid
33 infringing on user name space. This should be done even for local
34 variables, as they might otherwise be expanded by user macros.
35 There are some unavoidable exceptions within include files to
36 define necessary library symbols; they are noted "INFRINGES ON
37 USER NAME SPACE" below. */
39 /* Identify Bison output. */
40 #define YYBISON 1
42 /* Skeleton name. */
43 #define YYSKELETON_NAME "yacc.c"
45 /* Pure parsers. */
46 #define YYPURE 1
48 /* Using locations. */
49 #define YYLSP_NEEDED 0
51 /* If NAME_PREFIX is specified substitute the variables and functions
52 names. */
53 #define yyparse _gst_parse_yyparse
54 #define yylex _gst_parse_yylex
55 #define yyerror _gst_parse_yyerror
56 #define yylval _gst_parse_yylval
57 #define yychar _gst_parse_yychar
58 #define yydebug _gst_parse_yydebug
59 #define yynerrs _gst_parse_yynerrs
62 /* Tokens. */
63 #ifndef YYTOKENTYPE
64 # define YYTOKENTYPE
65 /* Put the tokens into the symbol table, so that GDB and other debuggers
66 know about them. */
67 enum yytokentype
68 {
69 PARSE_URL = 258,
70 IDENTIFIER = 259,
71 BINREF = 260,
72 PADREF = 261,
73 REF = 262,
74 ASSIGNMENT = 263,
75 LINK = 264
76 };
77 #endif
78 #define PARSE_URL 258
79 #define IDENTIFIER 259
80 #define BINREF 260
81 #define PADREF 261
82 #define REF 262
83 #define ASSIGNMENT 263
84 #define LINK 264
89 /* Copy the first part of user declarations. */
90 #line 1 "./grammar.y"
92 #include "../gst_private.h"
94 #include <glib-object.h>
95 #include <glib.h>
96 #include <stdio.h>
97 #include <string.h>
98 #include <stdlib.h>
100 #include "../gst-i18n-lib.h"
102 #include "../gstconfig.h"
103 #include "../gstparse.h"
104 #include "../gstinfo.h"
105 #include "../gsterror.h"
106 #include "../gststructure.h"
107 #include "../gsturi.h"
108 #include "../gstutils.h"
109 #include "../gstvalue.h"
110 #include "../gstchildproxy.h"
111 #include "types.h"
113 /* All error messages in this file are user-visible and need to be translated.
114 * Don't start the message with a capital, and don't end them with a period,
115 * as they will be presented inside a sentence/error.
116 */
118 #define YYERROR_VERBOSE 1
119 #define YYLEX_PARAM scanner
121 typedef void *yyscan_t;
123 int _gst_parse_yylex (void *yylval_param, yyscan_t yyscanner);
124 int _gst_parse_yylex_init (yyscan_t scanner);
125 int _gst_parse_yylex_destroy (yyscan_t scanner);
126 struct yy_buffer_state *_gst_parse_yy_scan_string (char *, yyscan_t);
127 void _gst_parse_yypush_buffer_state (void *new_buffer, yyscan_t yyscanner);
128 void _gst_parse_yypop_buffer_state (yyscan_t yyscanner);
131 #ifdef __GST_PARSE_TRACE
132 static guint __strings;
133 static guint __links;
134 static guint __chains;
135 gchar *
136 __gst_parse_strdup (gchar * org)
137 {
138 gchar *ret;
139 __strings++;
140 ret = g_strdup (org);
141 /* g_print ("ALLOCATED STR (%3u): %p %s\n", __strings, ret, ret); */
142 return ret;
143 }
145 void
146 __gst_parse_strfree (gchar * str)
147 {
148 if (str) {
149 /* g_print ("FREEING STR (%3u): %p %s\n", __strings - 1, str, str); */
150 g_free (str);
151 g_return_if_fail (__strings > 0);
152 __strings--;
153 }
154 }
156 link_t *
157 __gst_parse_link_new ()
158 {
159 link_t *ret;
160 __links++;
161 ret = g_slice_new0 (link_t);
162 /* g_print ("ALLOCATED LINK (%3u): %p\n", __links, ret); */
163 return ret;
164 }
166 void
167 __gst_parse_link_free (link_t * data)
168 {
169 if (data) {
170 /* g_print ("FREEING LINK (%3u): %p\n", __links - 1, data); */
171 g_slice_free (link_t, data);
172 g_return_if_fail (__links > 0);
173 __links--;
174 }
175 }
177 chain_t *
178 __gst_parse_chain_new ()
179 {
180 chain_t *ret;
181 __chains++;
182 ret = g_slice_new0 (chain_t);
183 /* g_print ("ALLOCATED CHAIN (%3u): %p\n", __chains, ret); */
184 return ret;
185 }
187 void
188 __gst_parse_chain_free (chain_t * data)
189 {
190 /* g_print ("FREEING CHAIN (%3u): %p\n", __chains - 1, data); */
191 g_slice_free (chain_t, data);
192 g_return_if_fail (__chains > 0);
193 __chains--;
194 }
196 #endif /* __GST_PARSE_TRACE */
198 typedef struct
199 {
200 gchar *src_pad;
201 gchar *sink_pad;
202 GstElement *sink;
203 GstCaps *caps;
204 gulong signal_id;
205 } DelayedLink;
207 typedef struct
208 {
209 GstElement *parent;
210 gchar *name;
211 gchar *value_str;
212 gulong signal_id;
213 } DelayedSet;
215 /*** define SET_ERROR macro/function */
217 #ifdef G_HAVE_ISO_VARARGS
219 # define SET_ERROR(error, type, ...) \
220 G_STMT_START { \
221 GST_CAT_ERROR (GST_CAT_PIPELINE, __VA_ARGS__); \
222 if ((error) && !*(error)) { \
223 g_set_error ((error), GST_PARSE_ERROR, (type), __VA_ARGS__); \
224 } \
225 } G_STMT_END
227 #elif defined(G_HAVE_GNUC_VARARGS)
229 # define SET_ERROR(error, type, args...) \
230 G_STMT_START { \
231 GST_CAT_ERROR (GST_CAT_PIPELINE, args ); \
232 if ((error) && !*(error)) { \
233 g_set_error ((error), GST_PARSE_ERROR, (type), args ); \
234 } \
235 } G_STMT_END
237 #else
239 static inline void
240 SET_ERROR (GError ** error, gint type, const char *format, ...)
241 {
242 if (error) {
243 if (*error) {
244 g_warning ("error while parsing");
245 } else {
246 va_list varargs;
247 char *string;
249 va_start (varargs, format);
250 string = g_strdup_vprintf (format, varargs);
251 va_end (varargs);
253 g_set_error (error, GST_PARSE_ERROR, type, string);
255 g_free (string);
256 }
257 }
258 }
260 #endif /* G_HAVE_ISO_VARARGS */
262 /*** define YYPRINTF macro/function if we're debugging */
264 /* bison 1.35 calls this macro with side effects, we need to make sure the
265 side effects work - crappy bison */
267 #ifndef GST_DISABLE_GST_DEBUG
268 # define YYDEBUG 1
270 # ifdef G_HAVE_ISO_VARARGS
272 /* # define YYFPRINTF(a, ...) GST_CAT_DEBUG (GST_CAT_PIPELINE, __VA_ARGS__) */
273 # define YYFPRINTF(a, ...) \
274 G_STMT_START { \
275 GST_CAT_LOG (GST_CAT_PIPELINE, __VA_ARGS__); \
276 } G_STMT_END
278 # elif defined(G_HAVE_GNUC_VARARGS)
280 # define YYFPRINTF(a, args...) \
281 G_STMT_START { \
282 GST_CAT_LOG (GST_CAT_PIPELINE, args); \
283 } G_STMT_END
285 # else
287 static inline void
288 YYPRINTF (const char *format, ...)
289 {
290 va_list varargs;
291 gchar *temp;
293 va_start (varargs, format);
294 temp = g_strdup_vprintf (format, varargs);
295 GST_CAT_LOG (GST_CAT_PIPELINE, "%s", temp);
296 g_free (temp);
297 va_end (varargs);
298 }
300 # endif /* G_HAVE_ISO_VARARGS */
302 #endif /* GST_DISABLE_GST_DEBUG */
304 #define ADD_MISSING_ELEMENT(graph,name) G_STMT_START { \
305 if ((graph)->ctx) { \
306 (graph)->ctx->missing_elements = \
307 g_list_append ((graph)->ctx->missing_elements, g_strdup (name)); \
308 } } G_STMT_END
310 #define GST_BIN_MAKE(res, type, chainval, assign, free_string) \
311 G_STMT_START { \
312 chain_t *chain = chainval; \
313 GSList *walk; \
314 GstBin *bin = (GstBin *) gst_element_factory_make (type, NULL); \
315 if (!chain) { \
316 SET_ERROR (graph->error, GST_PARSE_ERROR_EMPTY_BIN, \
317 _("specified empty bin \"%s\", not allowed"), type); \
318 g_slist_foreach (assign, (GFunc) gst_parse_strfree, NULL); \
319 g_slist_free (assign); \
320 gst_object_unref (bin); \
321 if (free_string) \
322 gst_parse_strfree (type); /* Need to clean up the string */ \
323 YYERROR; \
324 } else if (!bin) { \
325 ADD_MISSING_ELEMENT(graph, type); \
326 SET_ERROR (graph->error, GST_PARSE_ERROR_NO_SUCH_ELEMENT, \
327 _("no bin \"%s\", skipping"), type); \
328 g_slist_foreach (assign, (GFunc) gst_parse_strfree, NULL); \
329 g_slist_free (assign); \
330 res = chain; \
331 } else { \
332 for (walk = chain->elements; walk; walk = walk->next ) \
333 gst_bin_add (bin, GST_ELEMENT (walk->data)); \
334 g_slist_free (chain->elements); \
335 chain->elements = g_slist_prepend (NULL, bin); \
336 res = chain; \
337 /* set the properties now */ \
338 for (walk = assign; walk; walk = walk->next) \
339 gst_parse_element_set ((gchar *) walk->data, GST_ELEMENT (bin), graph); \
340 g_slist_free (assign); \
341 } \
342 } G_STMT_END
344 #define MAKE_LINK(link, _src, _src_name, _src_pads, _sink, _sink_name, _sink_pads) \
345 G_STMT_START { \
346 link = gst_parse_link_new (); \
347 link->src = _src; \
348 link->sink = _sink; \
349 link->src_name = _src_name; \
350 link->sink_name = _sink_name; \
351 link->src_pads = _src_pads; \
352 link->sink_pads = _sink_pads; \
353 link->caps = NULL; \
354 } G_STMT_END
356 #define MAKE_REF(link, _src, _pads) \
357 G_STMT_START { \
358 gchar *padname = _src; \
359 GSList *pads = _pads; \
360 if (padname) { \
361 while (*padname != '.') padname++; \
362 *padname = '\0'; \
363 padname++; \
364 if (*padname != '\0') \
365 pads = g_slist_prepend (pads, gst_parse_strdup (padname)); \
366 } \
367 MAKE_LINK (link, NULL, _src, pads, NULL, NULL, NULL); \
368 } G_STMT_END
370 static void
371 gst_parse_new_child (GstChildProxy * child_proxy, GObject * object,
372 gpointer data)
373 {
374 DelayedSet *set = (DelayedSet *) data;
375 GParamSpec *pspec;
376 GValue v = { 0, };
377 GstObject *target = NULL;
378 GType value_type;
380 if (gst_child_proxy_lookup (GST_OBJECT (set->parent), set->name, &target,
381 &pspec)) {
382 gboolean got_value = FALSE;
384 value_type = G_PARAM_SPEC_VALUE_TYPE (pspec);
386 GST_CAT_LOG (GST_CAT_PIPELINE,
387 "parsing delayed property %s as a %s from %s", pspec->name,
388 g_type_name (value_type), set->value_str);
389 g_value_init (&v, value_type);
390 if (gst_value_deserialize (&v, set->value_str))
391 got_value = TRUE;
392 else if (g_type_is_a (value_type, GST_TYPE_ELEMENT)) {
393 GstElement *bin;
395 bin = gst_parse_bin_from_description (set->value_str, TRUE, NULL);
396 if (bin) {
397 g_value_set_object (&v, bin);
398 got_value = TRUE;
399 }
400 }
401 g_signal_handler_disconnect (child_proxy, set->signal_id);
402 if (!got_value)
403 goto error;
404 g_object_set_property (G_OBJECT (target), pspec->name, &v);
405 }
407 out:
408 if (G_IS_VALUE (&v))
409 g_value_unset (&v);
410 if (target)
411 gst_object_unref (target);
412 return;
414 error:
415 GST_CAT_ERROR (GST_CAT_PIPELINE,
416 "could not set property \"%s\" in element \"%s\"", pspec->name,
417 GST_ELEMENT_NAME (target));
418 goto out;
419 }
421 static void
422 gst_parse_free_delayed_set (DelayedSet * set)
423 {
424 g_free (set->name);
425 g_free (set->value_str);
426 g_slice_free (DelayedSet, set);
427 }
429 static void
430 gst_parse_element_set (gchar * value, GstElement * element, graph_t * graph)
431 {
432 GParamSpec *pspec;
433 gchar *pos = value;
434 GValue v = { 0, };
435 GstObject *target = NULL;
436 GType value_type;
438 /* do nothing if assignment is for missing element */
439 if (element == NULL)
440 goto out;
442 /* parse the string, so the property name is null-terminated an pos points
443 to the beginning of the value */
444 while (!g_ascii_isspace (*pos) && (*pos != '='))
445 pos++;
446 if (*pos == '=') {
447 *pos = '\0';
448 } else {
449 *pos = '\0';
450 pos++;
451 while (g_ascii_isspace (*pos))
452 pos++;
453 }
454 pos++;
455 while (g_ascii_isspace (*pos))
456 pos++;
457 if (*pos == '"') {
458 pos++;
459 pos[strlen (pos) - 1] = '\0';
460 }
461 gst_parse_unescape (pos);
463 if (gst_child_proxy_lookup (GST_OBJECT (element), value, &target, &pspec)) {
464 gboolean got_value = FALSE;
466 value_type = G_PARAM_SPEC_VALUE_TYPE (pspec);
468 GST_CAT_LOG (GST_CAT_PIPELINE, "parsing property %s as a %s", pspec->name,
469 g_type_name (value_type));
470 g_value_init (&v, value_type);
471 if (gst_value_deserialize (&v, pos))
472 got_value = TRUE;
473 else if (g_type_is_a (value_type, GST_TYPE_ELEMENT)) {
474 GstElement *bin;
476 bin = gst_parse_bin_from_description (pos, TRUE, NULL);
477 if (bin) {
478 g_value_set_object (&v, bin);
479 got_value = TRUE;
480 }
481 }
482 if (!got_value)
483 goto error;
484 g_object_set_property (G_OBJECT (target), pspec->name, &v);
485 } else {
486 /* do a delayed set */
487 if (GST_IS_CHILD_PROXY (element)) {
488 DelayedSet *data = g_slice_new0 (DelayedSet);
490 data->parent = element;
491 data->name = g_strdup (value);
492 data->value_str = g_strdup (pos);
493 data->signal_id = g_signal_connect_data (element, "child-added",
494 G_CALLBACK (gst_parse_new_child), data, (GClosureNotify)
495 gst_parse_free_delayed_set, (GConnectFlags) 0);
496 } else {
497 SET_ERROR (graph->error, GST_PARSE_ERROR_NO_SUCH_PROPERTY,
498 _("no property \"%s\" in element \"%s\""), value,
499 GST_ELEMENT_NAME (element));
500 }
501 }
503 out:
504 gst_parse_strfree (value);
505 if (G_IS_VALUE (&v))
506 g_value_unset (&v);
507 if (target)
508 gst_object_unref (target);
509 return;
511 error:
512 SET_ERROR (graph->error, GST_PARSE_ERROR_COULD_NOT_SET_PROPERTY,
513 _("could not set property \"%s\" in element \"%s\" to \"%s\""),
514 value, GST_ELEMENT_NAME (element), pos);
515 goto out;
516 }
518 static inline void
519 gst_parse_free_link (link_t * link)
520 {
521 gst_parse_strfree (link->src_name);
522 gst_parse_strfree (link->sink_name);
523 g_slist_foreach (link->src_pads, (GFunc) gst_parse_strfree, NULL);
524 g_slist_foreach (link->sink_pads, (GFunc) gst_parse_strfree, NULL);
525 g_slist_free (link->src_pads);
526 g_slist_free (link->sink_pads);
527 if (link->caps)
528 gst_caps_unref (link->caps);
529 gst_parse_link_free (link);
530 }
532 static void
533 gst_parse_free_delayed_link (DelayedLink * link)
534 {
535 g_free (link->src_pad);
536 g_free (link->sink_pad);
537 if (link->caps)
538 gst_caps_unref (link->caps);
539 g_slice_free (DelayedLink, link);
540 }
542 static void
543 gst_parse_found_pad (GstElement * src, GstPad * pad, gpointer data)
544 {
545 DelayedLink *link = data;
547 GST_CAT_INFO (GST_CAT_PIPELINE, "trying delayed linking %s:%s to %s:%s",
548 GST_STR_NULL (GST_ELEMENT_NAME (src)), GST_STR_NULL (link->src_pad),
549 GST_STR_NULL (GST_ELEMENT_NAME (link->sink)),
550 GST_STR_NULL (link->sink_pad));
552 if (gst_element_link_pads_filtered (src, link->src_pad, link->sink,
553 link->sink_pad, link->caps)) {
554 /* do this here, we don't want to get any problems later on when
555 * unlocking states */
556 GST_CAT_DEBUG (GST_CAT_PIPELINE, "delayed linking %s:%s to %s:%s worked",
557 GST_STR_NULL (GST_ELEMENT_NAME (src)), GST_STR_NULL (link->src_pad),
558 GST_STR_NULL (GST_ELEMENT_NAME (link->sink)),
559 GST_STR_NULL (link->sink_pad));
560 g_signal_handler_disconnect (src, link->signal_id);
561 }
562 }
564 /* both padnames and the caps may be NULL */
565 static gboolean
566 gst_parse_perform_delayed_link (GstElement * src, const gchar * src_pad,
567 GstElement * sink, const gchar * sink_pad, GstCaps * caps)
568 {
569 GList *templs =
570 gst_element_class_get_pad_template_list (GST_ELEMENT_GET_CLASS (src));
572 for (; templs; templs = templs->next) {
573 GstPadTemplate *templ = (GstPadTemplate *) templs->data;
574 if ((GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SRC) &&
575 (GST_PAD_TEMPLATE_PRESENCE (templ) == GST_PAD_SOMETIMES)) {
576 DelayedLink *data = g_slice_new (DelayedLink);
578 /* TODO: maybe we should check if src_pad matches this template's names */
580 GST_CAT_DEBUG (GST_CAT_PIPELINE, "trying delayed link %s:%s to %s:%s",
581 GST_STR_NULL (GST_ELEMENT_NAME (src)), GST_STR_NULL (src_pad),
582 GST_STR_NULL (GST_ELEMENT_NAME (sink)), GST_STR_NULL (sink_pad));
584 data->src_pad = g_strdup (src_pad);
585 data->sink = sink;
586 data->sink_pad = g_strdup (sink_pad);
587 if (caps) {
588 data->caps = gst_caps_copy (caps);
589 } else {
590 data->caps = NULL;
591 }
592 data->signal_id = g_signal_connect_data (src, "pad-added",
593 G_CALLBACK (gst_parse_found_pad), data,
594 (GClosureNotify) gst_parse_free_delayed_link, (GConnectFlags) 0);
595 return TRUE;
596 }
597 }
598 return FALSE;
599 }
601 /*
602 * performs a link and frees the struct. src and sink elements must be given
603 * return values 0 - link performed
604 * 1 - link delayed
605 * <0 - error
606 */
607 static gint
608 gst_parse_perform_link (link_t * link, graph_t * graph)
609 {
610 GstElement *src = link->src;
611 GstElement *sink = link->sink;
612 GSList *srcs = link->src_pads;
613 GSList *sinks = link->sink_pads;
614 g_assert (GST_IS_ELEMENT (src));
615 g_assert (GST_IS_ELEMENT (sink));
617 GST_CAT_INFO (GST_CAT_PIPELINE,
618 "linking %s:%s to %s:%s (%u/%u) with caps \"%" GST_PTR_FORMAT "\"",
619 GST_ELEMENT_NAME (src), link->src_name ? link->src_name : "(any)",
620 GST_ELEMENT_NAME (sink), link->sink_name ? link->sink_name : "(any)",
621 g_slist_length (srcs), g_slist_length (sinks), link->caps);
623 if (!srcs || !sinks) {
624 if (gst_element_link_pads_filtered (src,
625 srcs ? (const gchar *) srcs->data : NULL, sink,
626 sinks ? (const gchar *) sinks->data : NULL, link->caps)) {
627 goto success;
628 } else {
629 if (gst_parse_perform_delayed_link (src,
630 srcs ? (const gchar *) srcs->data : NULL,
631 sink, sinks ? (const gchar *) sinks->data : NULL, link->caps)) {
632 goto success;
633 } else {
634 goto error;
635 }
636 }
637 }
638 if (g_slist_length (link->src_pads) != g_slist_length (link->src_pads)) {
639 goto error;
640 }
641 while (srcs && sinks) {
642 const gchar *src_pad = (const gchar *) srcs->data;
643 const gchar *sink_pad = (const gchar *) sinks->data;
644 srcs = g_slist_next (srcs);
645 sinks = g_slist_next (sinks);
646 if (gst_element_link_pads_filtered (src, src_pad, sink, sink_pad,
647 link->caps)) {
648 continue;
649 } else {
650 if (gst_parse_perform_delayed_link (src, src_pad,
651 sink, sink_pad, link->caps)) {
652 continue;
653 } else {
654 goto error;
655 }
656 }
657 }
659 success:
660 gst_parse_free_link (link);
661 return 0;
663 error:
664 SET_ERROR (graph->error, GST_PARSE_ERROR_LINK,
665 _("could not link %s to %s"), GST_ELEMENT_NAME (src),
666 GST_ELEMENT_NAME (sink));
667 gst_parse_free_link (link);
668 return -1;
669 }
672 static int yyerror (void *scanner, graph_t * graph, const char *s);
675 /* Enabling traces. */
676 #ifndef YYDEBUG
677 # define YYDEBUG 0
678 #endif
680 /* Enabling verbose error messages. */
681 #ifdef YYERROR_VERBOSE
682 # undef YYERROR_VERBOSE
683 # define YYERROR_VERBOSE 1
684 #else
685 # define YYERROR_VERBOSE 0
686 #endif
688 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
689 #line 566 "./grammar.y"
690 typedef union YYSTYPE
691 {
692 gchar *s;
693 chain_t *c;
694 link_t *l;
695 GstElement *e;
696 GSList *p;
697 graph_t *g;
698 } YYSTYPE;
699 /* Line 186 of yacc.c. */
700 #line 677 "grammar.tab.c"
701 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
702 # define YYSTYPE_IS_DECLARED 1
703 # define YYSTYPE_IS_TRIVIAL 1
704 #endif
708 /* Copy the second part of user declarations. */
711 /* Line 214 of yacc.c. */
712 #line 689 "grammar.tab.c"
714 #if ! defined (yyoverflow) || YYERROR_VERBOSE
716 # ifndef YYFREE
717 # define YYFREE free
718 # endif
719 # ifndef YYMALLOC
720 # define YYMALLOC malloc
721 # endif
723 /* The parser invokes alloca or malloc; define the necessary symbols. */
725 # ifdef YYSTACK_USE_ALLOCA
726 # if YYSTACK_USE_ALLOCA
727 # define YYSTACK_ALLOC alloca
728 # endif
729 # else
730 # if defined (alloca) || defined (_ALLOCA_H)
731 # define YYSTACK_ALLOC alloca
732 # else
733 # ifdef __GNUC__
734 # define YYSTACK_ALLOC __builtin_alloca
735 # endif
736 # endif
737 # endif
739 # ifdef YYSTACK_ALLOC
740 /* Pacify GCC's `empty if-body' warning. */
741 # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
742 # else
743 # if defined (__STDC__) || defined (__cplusplus)
744 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
745 # define YYSIZE_T size_t
746 # endif
747 # define YYSTACK_ALLOC YYMALLOC
748 # define YYSTACK_FREE YYFREE
749 # endif
750 #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
753 #if (! defined (yyoverflow) \
754 && (! defined (__cplusplus) \
755 || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
757 /* A type that is properly aligned for any stack member. */
758 union yyalloc
759 {
760 short int yyss;
761 YYSTYPE yyvs;
762 };
764 /* The size of the maximum gap between one aligned stack and the next. */
765 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
767 /* The size of an array large to enough to hold all stacks, each with
768 N elements. */
769 # define YYSTACK_BYTES(N) \
770 ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \
771 + YYSTACK_GAP_MAXIMUM)
773 /* Copy COUNT objects from FROM to TO. The source and destination do
774 not overlap. */
775 # ifndef YYCOPY
776 # if defined (__GNUC__) && 1 < __GNUC__
777 # define YYCOPY(To, From, Count) \
778 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
779 # else
780 # define YYCOPY(To, From, Count) \
781 do \
782 { \
783 register YYSIZE_T yyi; \
784 for (yyi = 0; yyi < (Count); yyi++) \
785 (To)[yyi] = (From)[yyi]; \
786 } \
787 while (0)
788 # endif
789 # endif
791 /* Relocate STACK from its old location to the new one. The
792 local variables YYSIZE and YYSTACKSIZE give the old and new number of
793 elements in the stack, and YYPTR gives the new location of the
794 stack. Advance YYPTR to a properly aligned location for the next
795 stack. */
796 # define YYSTACK_RELOCATE(Stack) \
797 do \
798 { \
799 YYSIZE_T yynewbytes; \
800 YYCOPY (&yyptr->Stack, Stack, yysize); \
801 Stack = &yyptr->Stack; \
802 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
803 yyptr += yynewbytes / sizeof (*yyptr); \
804 } \
805 while (0)
807 #endif
809 #if defined (__STDC__) || defined (__cplusplus)
810 typedef signed char yysigned_char;
811 #else
812 typedef short int yysigned_char;
813 #endif
815 /* YYFINAL -- State number of the termination state. */
816 #define YYFINAL 29
817 /* YYLAST -- Last index in YYTABLE. */
818 #define YYLAST 176
820 /* YYNTOKENS -- Number of terminals. */
821 #define YYNTOKENS 16
822 /* YYNNTS -- Number of nonterminals. */
823 #define YYNNTS 12
824 /* YYNRULES -- Number of rules. */
825 #define YYNRULES 32
826 /* YYNRULES -- Number of states. */
827 #define YYNSTATES 43
829 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
830 #define YYUNDEFTOK 2
831 #define YYMAXUTOK 264
833 #define YYTRANSLATE(YYX) \
834 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
836 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
837 static const unsigned char yytranslate[] = {
838 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
839 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
840 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
841 2, 2, 2, 14, 2, 2, 2, 2, 2, 2,
842 10, 11, 2, 2, 12, 2, 13, 2, 2, 2,
843 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
844 2, 15, 2, 2, 2, 2, 2, 2, 2, 2,
845 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
846 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
847 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
848 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
849 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
850 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
851 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
852 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
853 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
854 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
855 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
856 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
857 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
858 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
859 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
860 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
861 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
862 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
863 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
864 5, 6, 7, 8, 9
865 };
867 #if YYDEBUG
868 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
869 YYRHS. */
870 static const unsigned char yyprhs[] = {
871 0, 0, 3, 5, 8, 9, 12, 17, 22, 26,
872 31, 33, 36, 39, 43, 45, 48, 50, 52, 53,
873 57, 59, 62, 65, 67, 69, 72, 75, 78, 81,
874 84, 87, 88
875 };
877 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
878 static const yysigned_char yyrhs[] = {
879 27, 0, -1, 4, -1, 17, 8, -1, -1, 18,
880 8, -1, 10, 18, 26, 11, -1, 5, 18, 26,
881 11, -1, 5, 18, 11, -1, 5, 18, 1, 11,
882 -1, 6, -1, 6, 21, -1, 12, 4, -1, 12,
883 4, 21, -1, 7, -1, 7, 21, -1, 22, -1,
884 20, -1, -1, 23, 9, 23, -1, 24, -1, 24,
885 25, -1, 25, 1, -1, 17, -1, 19, -1, 26,
886 26, -1, 26, 25, -1, 26, 1, -1, 24, 26,
887 -1, 3, 26, -1, 24, 3, -1, -1, 26, -1
888 };
890 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
891 static const unsigned short int yyrline[] = {
892 0, 601, 601, 615, 619, 620, 622, 623, 626, 629,
893 634, 635, 639, 640, 643, 644, 647, 648, 649, 652,
894 665, 666, 667, 670, 675, 676, 711, 739, 740, 754,
895 774, 799, 802
896 };
897 #endif
899 #if YYDEBUG || YYERROR_VERBOSE
900 /* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
901 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
902 static const char *const yytname[] = {
903 "$end", "error", "$undefined", "PARSE_URL", "IDENTIFIER", "BINREF",
904 "PADREF", "REF", "ASSIGNMENT", "LINK", "'('", "')'", "','", "'.'", "'!'",
905 "'='", "$accept", "element", "assignments", "bin", "pads", "padlist",
906 "reference", "linkpart", "link", "linklist", "chain", "graph", 0
907 };
908 #endif
910 # ifdef YYPRINT
911 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
912 token YYLEX-NUM. */
913 static const unsigned short int yytoknum[] = {
914 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
915 40, 41, 44, 46, 33, 61
916 };
917 # endif
919 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
920 static const unsigned char yyr1[] = {
921 0, 16, 17, 17, 18, 18, 19, 19, 19, 19,
922 20, 20, 21, 21, 22, 22, 23, 23, 23, 24,
923 25, 25, 25, 26, 26, 26, 26, 26, 26, 26,
924 26, 27, 27
925 };
927 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
928 static const unsigned char yyr2[] = {
929 0, 2, 1, 2, 0, 2, 4, 4, 3, 4,
930 1, 2, 2, 3, 1, 2, 1, 1, 0, 3,
931 1, 2, 2, 1, 1, 2, 2, 2, 2, 2,
932 2, 0, 1
933 };
935 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
936 STATE-NUM when YYTABLE doesn't specify something else to do. Zero
937 means the default is an error. */
938 static const unsigned char yydefact[] = {
939 18, 18, 2, 4, 10, 14, 4, 23, 24, 17,
940 16, 0, 18, 0, 0, 0, 0, 0, 11, 15,
941 18, 3, 18, 30, 0, 27, 20, 0, 0, 1,
942 0, 5, 8, 0, 12, 0, 19, 0, 22, 9,
943 7, 13, 6
944 };
946 /* YYDEFGOTO[NTERM-NUM]. */
947 static const yysigned_char yydefgoto[] = {
948 -1, 7, 16, 8, 9, 18, 10, 11, 26, 27,
949 28, 14
950 };
952 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
953 STATE-NUM. */
954 #define YYPACT_NINF -6
955 static const short int yypact[] = {
956 134, 158, -6, -6, -1, -1, -6, 6, -6, -6,
957 -6, 7, 166, 101, 18, 30, 89, 16, -6, -6,
958 2, -6, 129, 142, 42, -6, 150, 54, 66, -6,
959 11, -6, -6, 111, -1, 122, -6, 78, -6, -6,
960 -6, -6, -6
961 };
963 /* YYPGOTO[NTERM-NUM]. */
964 static const yysigned_char yypgoto[] = {
965 -6, -6, 19, -6, -6, -5, -6, 10, 3, 12,
966 1, -6
967 };
969 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
970 positive, shift that token. If negative, reduce the rule which
971 number is the opposite. If zero, do what YYDEFACT says.
972 If YYTABLE_NINF, syntax error. */
973 #define YYTABLE_NINF -33
974 static const yysigned_char yytable[] = {
975 19, 13, 15, 12, 12, 1, 2, 3, 4, 5,
976 31, 17, 6, 24, 21, 12, 22, 33, 29, 12,
977 34, 35, 39, 12, 15, 20, 12, 24, 0, 41,
978 -29, 25, 36, 1, 2, 3, 4, 5, 37, -18,
979 6, -29, -28, 25, 0, 1, 2, 3, 4, 5,
980 0, -18, 6, -28, -26, 38, 0, -26, -26, -26,
981 -26, -26, 0, -26, -26, -26, -25, 25, 0, 1,
982 2, 3, 4, 5, 0, -18, 6, -25, -21, 38,
983 0, -21, -21, -21, -21, -21, 0, -21, -21, -21,
984 30, 0, 1, 2, 3, 4, 5, 31, -18, 6,
985 32, -32, 25, 0, 1, 2, 3, 4, 5, 0,
986 -18, 6, 25, 0, 1, 2, 3, 4, 5, 0,
987 -18, 6, 40, 25, 0, 1, 2, 3, 4, 5,
988 0, -18, 6, 42, -31, 4, 5, 1, 2, 3,
989 4, 5, 0, 0, 6, 1, 2, 3, 4, 5,
990 0, -18, 6, 23, 2, 3, 4, 5, 0, -18,
991 6, 1, 2, 3, 4, 5, 0, 0, 6, 23,
992 2, 3, 4, 5, 0, 0, 6
993 };
995 static const yysigned_char yycheck[] = {
996 5, 0, 1, 0, 1, 3, 4, 5, 6, 7,
997 8, 12, 10, 12, 8, 12, 9, 16, 0, 16,
998 4, 20, 11, 20, 23, 6, 23, 26, -1, 34,
999 0, 1, 22, 3, 4, 5, 6, 7, 26, 9,
1000 10, 11, 0, 1, -1, 3, 4, 5, 6, 7,
1001 -1, 9, 10, 11, 0, 1, -1, 3, 4, 5,
1002 6, 7, -1, 9, 10, 11, 0, 1, -1, 3,
1003 4, 5, 6, 7, -1, 9, 10, 11, 0, 1,
1004 -1, 3, 4, 5, 6, 7, -1, 9, 10, 11,
1005 1, -1, 3, 4, 5, 6, 7, 8, 9, 10,
1006 11, 0, 1, -1, 3, 4, 5, 6, 7, -1,
1007 9, 10, 1, -1, 3, 4, 5, 6, 7, -1,
1008 9, 10, 11, 1, -1, 3, 4, 5, 6, 7,
1009 -1, 9, 10, 11, 0, 6, 7, 3, 4, 5,
1010 6, 7, -1, -1, 10, 3, 4, 5, 6, 7,
1011 -1, 9, 10, 3, 4, 5, 6, 7, -1, 9,
1012 10, 3, 4, 5, 6, 7, -1, -1, 10, 3,
1013 4, 5, 6, 7, -1, -1, 10
1014 };
1016 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
1017 symbol of state STATE-NUM. */
1018 static const unsigned char yystos[] = {
1019 0, 3, 4, 5, 6, 7, 10, 17, 19, 20,
1020 22, 23, 24, 26, 27, 26, 18, 12, 21, 21,
1021 18, 8, 9, 3, 26, 1, 24, 25, 26, 0,
1022 1, 8, 11, 26, 4, 26, 23, 25, 1, 11,
1023 11, 21, 11
1024 };
1026 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
1027 # define YYSIZE_T __SIZE_TYPE__
1028 #endif
1029 #if ! defined (YYSIZE_T) && defined (size_t)
1030 # define YYSIZE_T size_t
1031 #endif
1032 #if ! defined (YYSIZE_T)
1033 # if defined (__STDC__) || defined (__cplusplus)
1034 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
1035 # define YYSIZE_T size_t
1036 # endif
1037 #endif
1038 #if ! defined (YYSIZE_T)
1039 # define YYSIZE_T unsigned int
1040 #endif
1042 #define yyerrok (yyerrstatus = 0)
1043 #define yyclearin (yychar = YYEMPTY)
1044 #define YYEMPTY (-2)
1045 #define YYEOF 0
1047 #define YYACCEPT goto yyacceptlab
1048 #define YYABORT goto yyabortlab
1049 #define YYERROR goto yyerrorlab
1052 /* Like YYERROR except do call yyerror. This remains here temporarily
1053 to ease the transition to the new meaning of YYERROR, for GCC.
1054 Once GCC version 2 has supplanted version 1, this can go. */
1056 #define YYFAIL goto yyerrlab
1058 #define YYRECOVERING() (!!yyerrstatus)
1060 #define YYBACKUP(Token, Value) \
1061 do \
1062 if (yychar == YYEMPTY && yylen == 1) \
1063 { \
1064 yychar = (Token); \
1065 yylval = (Value); \
1066 yytoken = YYTRANSLATE (yychar); \
1067 YYPOPSTACK; \
1068 goto yybackup; \
1069 } \
1070 else \
1071 { \
1072 yyerror (scanner, graph, "syntax error: cannot back up");\
1073 YYERROR; \
1074 } \
1075 while (0)
1077 #define YYTERROR 1
1078 #define YYERRCODE 256
1080 /* YYLLOC_DEFAULT -- Compute the default location (before the actions
1081 are run). */
1083 #ifndef YYLLOC_DEFAULT
1084 # define YYLLOC_DEFAULT(Current, Rhs, N) \
1085 ((Current).first_line = (Rhs)[1].first_line, \
1086 (Current).first_column = (Rhs)[1].first_column, \
1087 (Current).last_line = (Rhs)[N].last_line, \
1088 (Current).last_column = (Rhs)[N].last_column)
1089 #endif
1091 /* YYLEX -- calling `yylex' with the right arguments. */
1093 #ifdef YYLEX_PARAM
1094 # define YYLEX yylex (&yylval, YYLEX_PARAM)
1095 #else
1096 # define YYLEX yylex (&yylval)
1097 #endif
1099 /* Enable debugging if requested. */
1100 #if YYDEBUG
1102 # ifndef YYFPRINTF
1103 # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
1104 # define YYFPRINTF fprintf
1105 # endif
1107 # define YYDPRINTF(Args) \
1108 do { \
1109 if (yydebug) \
1110 YYFPRINTF Args; \
1111 } while (0)
1113 # define YYDSYMPRINT(Args) \
1114 do { \
1115 if (yydebug) \
1116 yysymprint Args; \
1117 } while (0)
1119 # define YYDSYMPRINTF(Title, Token, Value, Location) \
1120 do { \
1121 if (yydebug) \
1122 { \
1123 YYFPRINTF (stderr, "%s ", Title); \
1124 yysymprint (stderr, \
1125 Token, Value); \
1126 YYFPRINTF (stderr, "\n"); \
1127 } \
1128 } while (0)
1130 /*------------------------------------------------------------------.
1131 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
1132 | TOP (included). |
1133 `------------------------------------------------------------------*/
1135 #if defined (__STDC__) || defined (__cplusplus)
1136 static void
1137 yy_stack_print (short int *bottom, short int *top)
1138 #else
1139 static void
1140 yy_stack_print (bottom, top)
1141 short int *bottom;
1142 short int *top;
1143 #endif
1144 {
1145 YYFPRINTF (stderr, "Stack now");
1146 for ( /* Nothing. */ ; bottom <= top; ++bottom)
1147 YYFPRINTF (stderr, " %d", *bottom);
1148 YYFPRINTF (stderr, "\n");
1149 }
1151 # define YY_STACK_PRINT(Bottom, Top) \
1152 do { \
1153 if (yydebug) \
1154 yy_stack_print ((Bottom), (Top)); \
1155 } while (0)
1158 /*------------------------------------------------.
1159 | Report that the YYRULE is going to be reduced. |
1160 `------------------------------------------------*/
1162 #if defined (__STDC__) || defined (__cplusplus)
1163 static void
1164 yy_reduce_print (int yyrule)
1165 #else
1166 static void
1167 yy_reduce_print (yyrule)
1168 int yyrule;
1169 #endif
1170 {
1171 int yyi;
1172 unsigned int yylno = yyrline[yyrule];
1173 YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
1174 yyrule - 1, yylno);
1175 /* Print the symbols being reduced, and their result. */
1176 for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
1177 YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
1178 YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]);
1179 }
1181 # define YY_REDUCE_PRINT(Rule) \
1182 do { \
1183 if (yydebug) \
1184 yy_reduce_print (Rule); \
1185 } while (0)
1187 /* Nonzero means print parse trace. It is left uninitialized so that
1188 multiple parsers can coexist. */
1189 int yydebug;
1190 #else /* !YYDEBUG */
1191 # define YYDPRINTF(Args)
1192 # define YYDSYMPRINT(Args)
1193 # define YYDSYMPRINTF(Title, Token, Value, Location)
1194 # define YY_STACK_PRINT(Bottom, Top)
1195 # define YY_REDUCE_PRINT(Rule)
1196 #endif /* !YYDEBUG */
1199 /* YYINITDEPTH -- initial size of the parser's stacks. */
1200 #ifndef YYINITDEPTH
1201 # define YYINITDEPTH 200
1202 #endif
1204 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
1205 if the built-in stack extension method is used).
1207 Do not make this value too large; the results are undefined if
1208 SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
1209 evaluated with infinite-precision integer arithmetic. */
1211 #if defined (YYMAXDEPTH) && YYMAXDEPTH == 0
1212 # undef YYMAXDEPTH
1213 #endif
1215 #ifndef YYMAXDEPTH
1216 # define YYMAXDEPTH 10000
1217 #endif
1218 \f
1221 #if YYERROR_VERBOSE
1223 # ifndef yystrlen
1224 # if defined (__GLIBC__) && defined (_STRING_H)
1225 # define yystrlen strlen
1226 # else
1227 /* Return the length of YYSTR. */
1228 static YYSIZE_T
1229 # if defined (__STDC__) || defined (__cplusplus)
1230 yystrlen (const char *yystr)
1231 # else
1232 yystrlen (yystr)
1233 const char *yystr;
1234 # endif
1235 {
1236 register const char *yys = yystr;
1238 while (*yys++ != '\0')
1239 continue;
1241 return yys - yystr - 1;
1242 }
1243 # endif
1244 # endif
1246 # ifndef yystpcpy
1247 # if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
1248 # define yystpcpy stpcpy
1249 # else
1250 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
1251 YYDEST. */
1252 static char *
1253 # if defined (__STDC__) || defined (__cplusplus)
1254 yystpcpy (char *yydest, const char *yysrc)
1255 # else
1256 yystpcpy (yydest, yysrc)
1257 char *yydest;
1258 const char *yysrc;
1259 # endif
1260 {
1261 register char *yyd = yydest;
1262 register const char *yys = yysrc;
1264 while ((*yyd++ = *yys++) != '\0')
1265 continue;
1267 return yyd - 1;
1268 }
1269 # endif
1270 # endif
1272 #endif /* !YYERROR_VERBOSE */
1273 \f
1276 #if YYDEBUG
1277 /*--------------------------------.
1278 | Print this symbol on YYOUTPUT. |
1279 `--------------------------------*/
1281 #if defined (__STDC__) || defined (__cplusplus)
1282 static void
1283 yysymprint (FILE * yyoutput, int yytype, YYSTYPE * yyvaluep)
1284 #else
1285 static void
1286 yysymprint (yyoutput, yytype, yyvaluep)
1287 FILE *yyoutput;
1288 int yytype;
1289 YYSTYPE *yyvaluep;
1290 #endif
1291 {
1292 /* Pacify ``unused variable'' warnings. */
1293 (void) yyvaluep;
1295 if (yytype < YYNTOKENS) {
1296 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
1297 # ifdef YYPRINT
1298 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
1299 # endif
1300 } else
1301 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
1303 switch (yytype) {
1304 default:
1305 break;
1306 }
1307 YYFPRINTF (yyoutput, ")");
1308 }
1310 #endif /* ! YYDEBUG */
1311 /*-----------------------------------------------.
1312 | Release the memory associated to this symbol. |
1313 `-----------------------------------------------*/
1315 #if defined (__STDC__) || defined (__cplusplus)
1316 static void
1317 yydestruct (int yytype, YYSTYPE * yyvaluep)
1318 #else
1319 static void
1320 yydestruct (yytype, yyvaluep)
1321 int yytype;
1322 YYSTYPE *yyvaluep;
1323 #endif
1324 {
1325 /* Pacify ``unused variable'' warnings. */
1326 (void) yyvaluep;
1328 switch (yytype) {
1330 default:
1331 break;
1332 }
1333 }
1334 \f
1336 /* Prevent warnings from -Wmissing-prototypes. */
1338 #ifdef YYPARSE_PARAM
1339 # if defined (__STDC__) || defined (__cplusplus)
1340 int yyparse (void *YYPARSE_PARAM);
1341 # else
1342 int yyparse ();
1343 # endif
1344 #else /* ! YYPARSE_PARAM */
1345 #if defined (__STDC__) || defined (__cplusplus)
1346 int yyparse (void *scanner, graph_t * graph);
1347 #else
1348 int yyparse ();
1349 #endif
1350 #endif /* ! YYPARSE_PARAM */
1357 /*----------.
1358 | yyparse. |
1359 `----------*/
1361 #ifdef YYPARSE_PARAM
1362 # if defined (__STDC__) || defined (__cplusplus)
1363 int
1364 yyparse (void *YYPARSE_PARAM)
1365 # else
1366 int
1367 yyparse (YYPARSE_PARAM)
1368 void *YYPARSE_PARAM;
1369 # endif
1370 #else /* ! YYPARSE_PARAM */
1371 #if defined (__STDC__) || defined (__cplusplus)
1372 int
1373 yyparse (void *scanner, graph_t * graph)
1374 #else
1375 int
1376 yyparse (scanner, graph)
1377 void *scanner;
1378 graph_t *graph;
1379 #endif
1380 #endif
1381 {
1382 /* The lookahead symbol. */
1383 int yychar;
1385 /* The semantic value of the lookahead symbol. */
1386 YYSTYPE yylval;
1388 /* Number of syntax errors so far. */
1389 int yynerrs;
1391 register int yystate;
1392 register int yyn;
1393 int yyresult;
1394 /* Number of tokens to shift before error messages enabled. */
1395 int yyerrstatus;
1396 /* Lookahead token as an internal (translated) token number. */
1397 int yytoken = 0;
1399 /* Three stacks and their tools:
1400 `yyss': related to states,
1401 `yyvs': related to semantic values,
1402 `yyls': related to locations.
1404 Refer to the stacks thru separate pointers, to allow yyoverflow
1405 to reallocate them elsewhere. */
1407 /* The state stack. */
1408 short int yyssa[YYINITDEPTH];
1409 short int *yyss = yyssa;
1410 register short int *yyssp;
1412 /* The semantic value stack. */
1413 YYSTYPE yyvsa[YYINITDEPTH];
1414 YYSTYPE *yyvs = yyvsa;
1415 register YYSTYPE *yyvsp;
1419 #define YYPOPSTACK (yyvsp--, yyssp--)
1421 YYSIZE_T yystacksize = YYINITDEPTH;
1423 /* The variables used to return semantic value and location from the
1424 action routines. */
1425 YYSTYPE yyval;
1428 /* When reducing, the number of symbols on the RHS of the reduced
1429 rule. */
1430 int yylen;
1432 YYDPRINTF ((stderr, "Starting parse\n"));
1434 yystate = 0;
1435 yyerrstatus = 0;
1436 yynerrs = 0;
1437 yychar = YYEMPTY; /* Cause a token to be read. */
1439 /* Initialize stack pointers.
1440 Waste one element of value and location stack
1441 so that they stay on the same level as the state stack.
1442 The wasted elements are never initialized. */
1444 yyssp = yyss;
1445 yyvsp = yyvs;
1448 goto yysetstate;
1450 /*------------------------------------------------------------.
1451 | yynewstate -- Push a new state, which is found in yystate. |
1452 `------------------------------------------------------------*/
1453 yynewstate:
1454 /* In all cases, when you get here, the value and location stacks
1455 have just been pushed. so pushing a state here evens the stacks.
1456 */
1457 yyssp++;
1459 yysetstate:
1460 *yyssp = yystate;
1462 if (yyss + yystacksize - 1 <= yyssp) {
1463 /* Get the current used size of the three stacks, in elements. */
1464 YYSIZE_T yysize = yyssp - yyss + 1;
1466 #ifdef yyoverflow
1467 {
1468 /* Give user a chance to reallocate the stack. Use copies of
1469 these so that the &'s don't force the real ones into
1470 memory. */
1471 YYSTYPE *yyvs1 = yyvs;
1472 short int *yyss1 = yyss;
1475 /* Each stack pointer address is followed by the size of the
1476 data in use in that stack, in bytes. This used to be a
1477 conditional around just the two extra args, but that might
1478 be undefined if yyoverflow is a macro. */
1479 yyoverflow ("parser stack overflow",
1480 &yyss1, yysize * sizeof (*yyssp),
1481 &yyvs1, yysize * sizeof (*yyvsp), &yystacksize);
1483 yyss = yyss1;
1484 yyvs = yyvs1;
1485 }
1486 #else /* no yyoverflow */
1487 # ifndef YYSTACK_RELOCATE
1488 goto yyoverflowlab;
1489 # else
1490 /* Extend the stack our own way. */
1491 if (YYMAXDEPTH <= yystacksize)
1492 goto yyoverflowlab;
1493 yystacksize *= 2;
1494 if (YYMAXDEPTH < yystacksize)
1495 yystacksize = YYMAXDEPTH;
1497 {
1498 short int *yyss1 = yyss;
1499 union yyalloc *yyptr =
1500 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1501 if (!yyptr)
1502 goto yyoverflowlab;
1503 YYSTACK_RELOCATE (yyss);
1504 YYSTACK_RELOCATE (yyvs);
1506 # undef YYSTACK_RELOCATE
1507 if (yyss1 != yyssa)
1508 YYSTACK_FREE (yyss1);
1509 }
1510 # endif
1511 #endif /* no yyoverflow */
1513 yyssp = yyss + yysize - 1;
1514 yyvsp = yyvs + yysize - 1;
1517 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1518 (unsigned long int) yystacksize));
1520 if (yyss + yystacksize - 1 <= yyssp)
1521 YYABORT;
1522 }
1524 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1526 goto yybackup;
1528 /*-----------.
1529 | yybackup. |
1530 `-----------*/
1531 yybackup:
1533 /* Do appropriate processing given the current state. */
1534 /* Read a lookahead token if we need one and don't already have one. */
1535 /* yyresume: */
1537 /* First try to decide what to do without reference to lookahead token. */
1539 yyn = yypact[yystate];
1540 if (yyn == YYPACT_NINF)
1541 goto yydefault;
1543 /* Not known => get a lookahead token if don't already have one. */
1545 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1546 if (yychar == YYEMPTY) {
1547 YYDPRINTF ((stderr, "Reading a token: "));
1548 yychar = YYLEX;
1549 }
1551 if (yychar <= YYEOF) {
1552 yychar = yytoken = YYEOF;
1553 YYDPRINTF ((stderr, "Now at end of input.\n"));
1554 } else {
1555 yytoken = YYTRANSLATE (yychar);
1556 YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
1557 }
1559 /* If the proper action on seeing token YYTOKEN is to reduce or to
1560 detect an error, take that action. */
1561 yyn += yytoken;
1562 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1563 goto yydefault;
1564 yyn = yytable[yyn];
1565 if (yyn <= 0) {
1566 if (yyn == 0 || yyn == YYTABLE_NINF)
1567 goto yyerrlab;
1568 yyn = -yyn;
1569 goto yyreduce;
1570 }
1572 if (yyn == YYFINAL)
1573 YYACCEPT;
1575 /* Shift the lookahead token. */
1576 YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
1578 /* Discard the token being shifted unless it is eof. */
1579 if (yychar != YYEOF)
1580 yychar = YYEMPTY;
1582 *++yyvsp = yylval;
1585 /* Count tokens shifted since error; after three, turn off error
1586 status. */
1587 if (yyerrstatus)
1588 yyerrstatus--;
1590 yystate = yyn;
1591 goto yynewstate;
1594 /*-----------------------------------------------------------.
1595 | yydefault -- do the default action for the current state. |
1596 `-----------------------------------------------------------*/
1597 yydefault:
1598 yyn = yydefact[yystate];
1599 if (yyn == 0)
1600 goto yyerrlab;
1601 goto yyreduce;
1604 /*-----------------------------.
1605 | yyreduce -- Do a reduction. |
1606 `-----------------------------*/
1607 yyreduce:
1608 /* yyn is the number of a rule to reduce with. */
1609 yylen = yyr2[yyn];
1611 /* If YYLEN is nonzero, implement the default value of the action:
1612 `$$ = $1'.
1614 Otherwise, the following line sets YYVAL to garbage.
1615 This behavior is undocumented and Bison
1616 users should not rely upon it. Assigning to YYVAL
1617 unconditionally makes the parser a bit smaller, and it avoids a
1618 GCC warning that YYVAL may be used uninitialized. */
1619 yyval = yyvsp[1 - yylen];
1622 YY_REDUCE_PRINT (yyn);
1623 switch (yyn) {
1624 case 2:
1625 #line 601 "./grammar.y"
1626 {
1627 yyval.e = gst_element_factory_make (yyvsp[0].s, NULL);
1628 if (yyval.e == NULL) {
1629 ADD_MISSING_ELEMENT (graph, yyvsp[0].s);
1630 SET_ERROR (graph->error, GST_PARSE_ERROR_NO_SUCH_ELEMENT,
1631 _("no element \"%s\""), yyvsp[0].s);
1632 /* if FATAL_ERRORS flag is set, we don't have to worry about backwards
1633 * compatibility and can continue parsing and check for other missing
1634 * elements */
1635 if ((graph->flags & GST_PARSE_FLAG_FATAL_ERRORS) == 0) {
1636 gst_parse_strfree (yyvsp[0].s);
1637 YYERROR;
1638 }
1639 }
1640 gst_parse_strfree (yyvsp[0].s);
1641 ;
1642 }
1643 break;
1645 case 3:
1646 #line 615 "./grammar.y"
1647 {
1648 gst_parse_element_set (yyvsp[0].s, yyvsp[-1].e, graph);
1649 yyval.e = yyvsp[-1].e;
1650 ;
1651 }
1652 break;
1654 case 4:
1655 #line 619 "./grammar.y"
1656 {
1657 yyval.p = NULL;;
1658 }
1659 break;
1661 case 5:
1662 #line 620 "./grammar.y"
1663 {
1664 yyval.p = g_slist_prepend (yyvsp[-1].p, yyvsp[0].s);;
1665 }
1666 break;
1668 case 6:
1669 #line 622 "./grammar.y"
1670 {
1671 GST_BIN_MAKE (yyval.c, "bin", yyvsp[-1].c, yyvsp[-2].p, FALSE);;
1672 }
1673 break;
1675 case 7:
1676 #line 623 "./grammar.y"
1677 {
1678 GST_BIN_MAKE (yyval.c, yyvsp[-3].s, yyvsp[-1].c, yyvsp[-2].p, TRUE);
1679 gst_parse_strfree (yyvsp[-3].s);
1680 ;
1681 }
1682 break;
1684 case 8:
1685 #line 626 "./grammar.y"
1686 {
1687 GST_BIN_MAKE (yyval.c, yyvsp[-2].s, NULL, yyvsp[-1].p, TRUE);
1688 gst_parse_strfree (yyvsp[-2].s);
1689 ;
1690 }
1691 break;
1693 case 9:
1694 #line 629 "./grammar.y"
1695 {
1696 GST_BIN_MAKE (yyval.c, yyvsp[-3].s, NULL, yyvsp[-2].p, TRUE);
1697 gst_parse_strfree (yyvsp[-3].s);
1698 ;
1699 }
1700 break;
1702 case 10:
1703 #line 634 "./grammar.y"
1704 {
1705 yyval.p = g_slist_prepend (NULL, yyvsp[0].s);;
1706 }
1707 break;
1709 case 11:
1710 #line 635 "./grammar.y"
1711 {
1712 yyval.p = yyvsp[0].p;
1713 yyval.p = g_slist_prepend (yyval.p, yyvsp[-1].s);
1714 ;
1715 }
1716 break;
1718 case 12:
1719 #line 639 "./grammar.y"
1720 {
1721 yyval.p = g_slist_prepend (NULL, yyvsp[0].s);;
1722 }
1723 break;
1725 case 13:
1726 #line 640 "./grammar.y"
1727 {
1728 yyval.p = g_slist_prepend (yyvsp[0].p, yyvsp[-1].s);;
1729 }
1730 break;
1732 case 14:
1733 #line 643 "./grammar.y"
1734 {
1735 MAKE_REF (yyval.l, yyvsp[0].s, NULL);;
1736 }
1737 break;
1739 case 15:
1740 #line 644 "./grammar.y"
1741 {
1742 MAKE_REF (yyval.l, yyvsp[-1].s, yyvsp[0].p);;
1743 }
1744 break;
1746 case 16:
1747 #line 647 "./grammar.y"
1748 {
1749 yyval.l = yyvsp[0].l;;
1750 }
1751 break;
1753 case 17:
1754 #line 648 "./grammar.y"
1755 {
1756 MAKE_REF (yyval.l, NULL, yyvsp[0].p);;
1757 }
1758 break;
1760 case 18:
1761 #line 649 "./grammar.y"
1762 {
1763 MAKE_REF (yyval.l, NULL, NULL);;
1764 }
1765 break;
1767 case 19:
1768 #line 652 "./grammar.y"
1769 {
1770 yyval.l = yyvsp[-2].l;
1771 if (yyvsp[-1].s) {
1772 yyval.l->caps = gst_caps_from_string (yyvsp[-1].s);
1773 if (yyval.l->caps == NULL)
1774 SET_ERROR (graph->error, GST_PARSE_ERROR_LINK,
1775 _("could not parse caps \"%s\""), yyvsp[-1].s);
1776 gst_parse_strfree (yyvsp[-1].s);
1777 }
1778 yyval.l->sink_name = yyvsp[0].l->src_name;
1779 yyval.l->sink_pads = yyvsp[0].l->src_pads;
1780 gst_parse_link_free (yyvsp[0].l);
1781 ;
1782 }
1783 break;
1785 case 20:
1786 #line 665 "./grammar.y"
1787 {
1788 yyval.p = g_slist_prepend (NULL, yyvsp[0].l);;
1789 }
1790 break;
1792 case 21:
1793 #line 666 "./grammar.y"
1794 {
1795 yyval.p = g_slist_prepend (yyvsp[0].p, yyvsp[-1].l);;
1796 }
1797 break;
1799 case 22:
1800 #line 667 "./grammar.y"
1801 {
1802 yyval.p = yyvsp[-1].p;;
1803 }
1804 break;
1806 case 23:
1807 #line 670 "./grammar.y"
1808 {
1809 yyval.c = gst_parse_chain_new ();
1810 yyval.c->first = yyval.c->last = yyvsp[0].e;
1811 yyval.c->front = yyval.c->back = NULL;
1812 yyval.c->elements = g_slist_prepend (NULL, yyvsp[0].e);
1813 ;
1814 }
1815 break;
1817 case 24:
1818 #line 675 "./grammar.y"
1819 {
1820 yyval.c = yyvsp[0].c;;
1821 }
1822 break;
1824 case 25:
1825 #line 676 "./grammar.y"
1826 {
1827 if (yyvsp[-1].c->back && yyvsp[0].c->front) {
1828 if (!yyvsp[-1].c->back->sink_name) {
1829 SET_ERROR (graph->error, GST_PARSE_ERROR_LINK,
1830 _("link without source element"));
1831 gst_parse_free_link (yyvsp[-1].c->back);
1832 } else {
1833 graph->links = g_slist_prepend (graph->links, yyvsp[-1].c->back);
1834 }
1835 if (!yyvsp[0].c->front->src_name) {
1836 SET_ERROR (graph->error, GST_PARSE_ERROR_LINK,
1837 _("link without sink element"));
1838 gst_parse_free_link (yyvsp[0].c->front);
1839 } else {
1840 graph->links = g_slist_prepend (graph->links, yyvsp[0].c->front);
1841 }
1842 yyvsp[-1].c->back = NULL;
1843 } else if (yyvsp[-1].c->back) {
1844 if (!yyvsp[-1].c->back->sink_name) {
1845 yyvsp[-1].c->back->sink = yyvsp[0].c->first;
1846 }
1847 } else if (yyvsp[0].c->front) {
1848 if (!yyvsp[0].c->front->src_name) {
1849 yyvsp[0].c->front->src = yyvsp[-1].c->last;
1850 }
1851 yyvsp[-1].c->back = yyvsp[0].c->front;
1852 }
1854 if (yyvsp[-1].c->back) {
1855 graph->links = g_slist_prepend (graph->links, yyvsp[-1].c->back);
1856 }
1857 yyvsp[-1].c->last = yyvsp[0].c->last;
1858 yyvsp[-1].c->back = yyvsp[0].c->back;
1859 yyvsp[-1].c->elements =
1860 g_slist_concat (yyvsp[-1].c->elements, yyvsp[0].c->elements);
1861 if (yyvsp[0].c)
1862 gst_parse_chain_free (yyvsp[0].c);
1863 yyval.c = yyvsp[-1].c;
1864 ;
1865 }
1866 break;
1868 case 26:
1869 #line 711 "./grammar.y"
1870 {
1871 GSList *walk;
1872 if (yyvsp[-1].c->back) {
1873 yyvsp[0].p = g_slist_prepend (yyvsp[0].p, yyvsp[-1].c->back);
1874 yyvsp[-1].c->back = NULL;
1875 } else {
1876 if (!((link_t *) yyvsp[0].p->data)->src_name) {
1877 ((link_t *) yyvsp[0].p->data)->src = yyvsp[-1].c->last;
1878 }
1879 }
1880 for (walk = yyvsp[0].p; walk; walk = walk->next) {
1881 link_t *link = (link_t *) walk->data;
1882 if (!link->sink_name && walk->next) {
1883 SET_ERROR (graph->error, GST_PARSE_ERROR_LINK,
1884 _("link without sink element"));
1885 gst_parse_free_link (link);
1886 } else if (!link->src_name && !link->src) {
1887 SET_ERROR (graph->error, GST_PARSE_ERROR_LINK,
1888 _("link without source element"));
1889 gst_parse_free_link (link);
1890 } else {
1891 if (walk->next) {
1892 graph->links = g_slist_prepend (graph->links, link);
1893 } else {
1894 yyvsp[-1].c->back = link;
1895 }
1896 }
1897 }
1898 g_slist_free (yyvsp[0].p);
1899 yyval.c = yyvsp[-1].c;
1900 ;
1901 }
1902 break;
1904 case 27:
1905 #line 739 "./grammar.y"
1906 {
1907 yyval.c = yyvsp[-1].c;;
1908 }
1909 break;
1911 case 28:
1912 #line 740 "./grammar.y"
1913 {
1914 if (yyvsp[0].c->front) {
1915 if (!yyvsp[0].c->front->src_name) {
1916 SET_ERROR (graph->error, GST_PARSE_ERROR_LINK,
1917 _("link without source element"));
1918 gst_parse_free_link (yyvsp[0].c->front);
1919 } else {
1920 graph->links = g_slist_prepend (graph->links, yyvsp[0].c->front);
1921 }
1922 }
1923 if (!yyvsp[-1].l->sink_name) {
1924 yyvsp[-1].l->sink = yyvsp[0].c->first;
1925 }
1926 yyvsp[0].c->front = yyvsp[-1].l;
1927 yyval.c = yyvsp[0].c;
1928 ;
1929 }
1930 break;
1932 case 29:
1933 #line 754 "./grammar.y"
1934 {
1935 yyval.c = yyvsp[0].c;
1936 if (yyval.c->front) {
1937 GstElement *element =
1938 gst_element_make_from_uri (GST_URI_SRC, yyvsp[-1].s, NULL);
1939 if (!element) {
1940 SET_ERROR (graph->error, GST_PARSE_ERROR_NO_SUCH_ELEMENT,
1941 _("no source element for URI \"%s\""), yyvsp[-1].s);
1942 } else {
1943 yyval.c->front->src = element;
1944 graph->links = g_slist_prepend (graph->links, yyval.c->front);
1945 yyval.c->front = NULL;
1946 yyval.c->elements = g_slist_prepend (yyval.c->elements, element);
1947 }
1948 } else {
1949 SET_ERROR (graph->error, GST_PARSE_ERROR_LINK,
1950 _("no element to link URI \"%s\" to"), yyvsp[-1].s);
1951 }
1952 g_free (yyvsp[-1].s);
1953 ;
1954 }
1955 break;
1957 case 30:
1958 #line 774 "./grammar.y"
1959 {
1960 GstElement *element =
1961 gst_element_make_from_uri (GST_URI_SINK, yyvsp[0].s, NULL);
1962 if (!element) {
1963 SET_ERROR (graph->error, GST_PARSE_ERROR_NO_SUCH_ELEMENT,
1964 _("no sink element for URI \"%s\""), yyvsp[0].s);
1965 gst_parse_link_free (yyvsp[-1].l);
1966 g_free (yyvsp[0].s);
1967 YYERROR;
1968 } else if (yyvsp[-1].l->sink_name || yyvsp[-1].l->sink_pads) {
1969 gst_object_unref (element);
1970 SET_ERROR (graph->error, GST_PARSE_ERROR_LINK,
1971 _("could not link sink element for URI \"%s\""), yyvsp[0].s);
1972 gst_parse_link_free (yyvsp[-1].l);
1973 g_free (yyvsp[0].s);
1974 YYERROR;
1975 } else {
1976 yyval.c = gst_parse_chain_new ();
1977 yyval.c->first = yyval.c->last = element;
1978 yyval.c->front = yyvsp[-1].l;
1979 yyval.c->front->sink = element;
1980 yyval.c->elements = g_slist_prepend (NULL, element);
1981 }
1982 g_free (yyvsp[0].s);
1983 ;
1984 }
1985 break;
1987 case 31:
1988 #line 799 "./grammar.y"
1989 {
1990 SET_ERROR (graph->error, GST_PARSE_ERROR_EMPTY,
1991 _("empty pipeline not allowed"));
1992 yyval.g = graph;
1993 ;
1994 }
1995 break;
1997 case 32:
1998 #line 802 "./grammar.y"
1999 {
2000 yyval.g = graph;
2001 if (yyvsp[0].c->front) {
2002 if (!yyvsp[0].c->front->src_name) {
2003 SET_ERROR (graph->error, GST_PARSE_ERROR_LINK,
2004 _("link without source element"));
2005 gst_parse_free_link (yyvsp[0].c->front);
2006 } else {
2007 yyval.g->links = g_slist_prepend (yyval.g->links, yyvsp[0].c->front);
2008 }
2009 yyvsp[0].c->front = NULL;
2010 }
2011 if (yyvsp[0].c->back) {
2012 if (!yyvsp[0].c->back->sink_name) {
2013 SET_ERROR (graph->error, GST_PARSE_ERROR_LINK,
2014 _("link without sink element"));
2015 gst_parse_free_link (yyvsp[0].c->back);
2016 } else {
2017 yyval.g->links = g_slist_prepend (yyval.g->links, yyvsp[0].c->back);
2018 }
2019 yyvsp[0].c->back = NULL;
2020 }
2021 yyval.g->chain = yyvsp[0].c;
2022 ;
2023 }
2024 break;
2027 }
2029 /* Line 1010 of yacc.c. */
2030 #line 1961 "grammar.tab.c"
2031 \f
2032 yyvsp -= yylen;
2033 yyssp -= yylen;
2036 YY_STACK_PRINT (yyss, yyssp);
2038 *++yyvsp = yyval;
2041 /* Now `shift' the result of the reduction. Determine what state
2042 that goes to, based on the state we popped back to and the rule
2043 number reduced by. */
2045 yyn = yyr1[yyn];
2047 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
2048 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
2049 yystate = yytable[yystate];
2050 else
2051 yystate = yydefgoto[yyn - YYNTOKENS];
2053 goto yynewstate;
2056 /*------------------------------------.
2057 | yyerrlab -- here on detecting error |
2058 `------------------------------------*/
2059 yyerrlab:
2060 /* If not already recovering from an error, report this error. */
2061 if (!yyerrstatus) {
2062 ++yynerrs;
2063 #if YYERROR_VERBOSE
2064 yyn = yypact[yystate];
2066 if (YYPACT_NINF < yyn && yyn < YYLAST) {
2067 YYSIZE_T yysize = 0;
2068 int yytype = YYTRANSLATE (yychar);
2069 const char *yyprefix;
2070 char *yymsg;
2071 int yyx;
2073 /* Start YYX at -YYN if negative to avoid negative indexes in
2074 YYCHECK. */
2075 int yyxbegin = yyn < 0 ? -yyn : 0;
2077 /* Stay within bounds of both yycheck and yytname. */
2078 int yychecklim = YYLAST - yyn;
2079 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
2080 int yycount = 0;
2082 yyprefix = ", expecting ";
2083 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
2084 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) {
2085 yysize += yystrlen (yyprefix) + yystrlen (yytname[yyx]);
2086 yycount += 1;
2087 if (yycount == 5) {
2088 yysize = 0;
2089 break;
2090 }
2091 }
2092 yysize += (sizeof ("syntax error, unexpected ")
2093 + yystrlen (yytname[yytype]));
2094 yymsg = (char *) YYSTACK_ALLOC (yysize);
2095 if (yymsg != 0) {
2096 char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
2097 yyp = yystpcpy (yyp, yytname[yytype]);
2099 if (yycount < 5) {
2100 yyprefix = ", expecting ";
2101 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
2102 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) {
2103 yyp = yystpcpy (yyp, yyprefix);
2104 yyp = yystpcpy (yyp, yytname[yyx]);
2105 yyprefix = " or ";
2106 }
2107 }
2108 yyerror (scanner, graph, yymsg);
2109 YYSTACK_FREE (yymsg);
2110 } else
2111 yyerror (scanner, graph, "syntax error; also virtual memory exhausted");
2112 } else
2113 #endif /* YYERROR_VERBOSE */
2114 yyerror (scanner, graph, "syntax error");
2115 }
2119 if (yyerrstatus == 3) {
2120 /* If just tried and failed to reuse lookahead token after an
2121 error, discard it. */
2123 if (yychar <= YYEOF) {
2124 /* If at end of input, pop the error token,
2125 then the rest of the stack, then return failure. */
2126 if (yychar == YYEOF)
2127 for (;;) {
2128 YYPOPSTACK;
2129 if (yyssp == yyss)
2130 YYABORT;
2131 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
2132 yydestruct (yystos[*yyssp], yyvsp);
2133 }
2134 } else {
2135 YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
2136 yydestruct (yytoken, &yylval);
2137 yychar = YYEMPTY;
2139 }
2140 }
2142 /* Else will try to reuse lookahead token after shifting the error
2143 token. */
2144 goto yyerrlab1;
2147 /*---------------------------------------------------.
2148 | yyerrorlab -- error raised explicitly by YYERROR. |
2149 `---------------------------------------------------*/
2150 yyerrorlab:
2152 #ifdef __GNUC__
2153 /* Pacify GCC when the user code never invokes YYERROR and the label
2154 yyerrorlab therefore never appears in user code. */
2155 if (0)
2156 goto yyerrorlab;
2157 #endif
2159 yyvsp -= yylen;
2160 yyssp -= yylen;
2161 yystate = *yyssp;
2162 goto yyerrlab1;
2165 /*-------------------------------------------------------------.
2166 | yyerrlab1 -- common code for both syntax error and YYERROR. |
2167 `-------------------------------------------------------------*/
2168 yyerrlab1:
2169 yyerrstatus = 3; /* Each real token shifted decrements this. */
2171 for (;;) {
2172 yyn = yypact[yystate];
2173 if (yyn != YYPACT_NINF) {
2174 yyn += YYTERROR;
2175 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) {
2176 yyn = yytable[yyn];
2177 if (0 < yyn)
2178 break;
2179 }
2180 }
2182 /* Pop the current state because it cannot handle the error token. */
2183 if (yyssp == yyss)
2184 YYABORT;
2186 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
2187 yydestruct (yystos[yystate], yyvsp);
2188 YYPOPSTACK;
2189 yystate = *yyssp;
2190 YY_STACK_PRINT (yyss, yyssp);
2191 }
2193 if (yyn == YYFINAL)
2194 YYACCEPT;
2196 YYDPRINTF ((stderr, "Shifting error token, "));
2198 *++yyvsp = yylval;
2201 yystate = yyn;
2202 goto yynewstate;
2205 /*-------------------------------------.
2206 | yyacceptlab -- YYACCEPT comes here. |
2207 `-------------------------------------*/
2208 yyacceptlab:
2209 yyresult = 0;
2210 goto yyreturn;
2212 /*-----------------------------------.
2213 | yyabortlab -- YYABORT comes here. |
2214 `-----------------------------------*/
2215 yyabortlab:
2216 yyresult = 1;
2217 goto yyreturn;
2219 #ifndef yyoverflow
2220 /*----------------------------------------------.
2221 | yyoverflowlab -- parser overflow comes here. |
2222 `----------------------------------------------*/
2223 yyoverflowlab:
2224 yyerror (scanner, graph, "parser stack overflow");
2225 yyresult = 2;
2226 /* Fall through. */
2227 #endif
2229 yyreturn:
2230 #ifndef yyoverflow
2231 if (yyss != yyssa)
2232 YYSTACK_FREE (yyss);
2233 #endif
2234 return yyresult;
2235 }
2238 #line 825 "./grammar.y"
2242 static int
2243 yyerror (void *scanner, graph_t * graph, const char *s)
2244 {
2245 /* FIXME: This should go into the GError somehow, but how? */
2246 GST_WARNING ("Error during parsing: %s", s);
2247 return -1;
2248 }
2251 GstElement *
2252 _gst_parse_launch (const gchar * str, GError ** error, GstParseContext * ctx,
2253 GstParseFlags flags)
2254 {
2255 graph_t g;
2256 gchar *dstr;
2257 GSList *walk;
2258 GstBin *bin = NULL;
2259 GstElement *ret;
2260 yyscan_t scanner;
2262 g_return_val_if_fail (str != NULL, NULL);
2263 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
2265 g.chain = NULL;
2266 g.links = NULL;
2267 g.error = error;
2268 g.ctx = ctx;
2269 g.flags = flags;
2271 #ifdef __GST_PARSE_TRACE
2272 GST_CAT_DEBUG (GST_CAT_PIPELINE, "TRACE: tracing enabled");
2273 __strings = __chains = __links = 0;
2274 #endif /* __GST_PARSE_TRACE */
2276 dstr = g_strdup (str);
2277 _gst_parse_yylex_init (&scanner);
2278 _gst_parse_yy_scan_string (dstr, scanner);
2280 #ifndef YYDEBUG
2281 yydebug = 1;
2282 #endif
2284 if (yyparse (scanner, &g) != 0) {
2285 SET_ERROR (error, GST_PARSE_ERROR_SYNTAX,
2286 "Unrecoverable syntax error while parsing pipeline %s", str);
2288 _gst_parse_yylex_destroy (scanner);
2289 g_free (dstr);
2291 goto error1;
2292 }
2293 _gst_parse_yylex_destroy (scanner);
2294 g_free (dstr);
2296 GST_CAT_DEBUG (GST_CAT_PIPELINE, "got %u elements and %u links",
2297 g.chain ? g_slist_length (g.chain->elements) : 0,
2298 g_slist_length (g.links));
2300 if (!g.chain) {
2301 ret = NULL;
2302 } else if (!g.chain->elements->next) {
2303 /* only one toplevel element */
2304 ret = (GstElement *) g.chain->elements->data;
2305 g_slist_free (g.chain->elements);
2306 if (GST_IS_BIN (ret))
2307 bin = GST_BIN (ret);
2308 gst_parse_chain_free (g.chain);
2309 } else {
2310 /* put all elements in our bin */
2311 bin = GST_BIN (gst_element_factory_make ("pipeline", NULL));
2312 g_assert (bin);
2314 for (walk = g.chain->elements; walk; walk = walk->next) {
2315 if (walk->data != NULL)
2316 gst_bin_add (bin, GST_ELEMENT (walk->data));
2317 }
2319 g_slist_free (g.chain->elements);
2320 ret = GST_ELEMENT (bin);
2321 gst_parse_chain_free (g.chain);
2322 }
2324 /* remove links */
2325 for (walk = g.links; walk; walk = walk->next) {
2326 link_t *l = (link_t *) walk->data;
2327 if (!l->src) {
2328 if (l->src_name) {
2329 if (bin) {
2330 l->src = gst_bin_get_by_name_recurse_up (bin, l->src_name);
2331 if (l->src)
2332 gst_object_unref (l->src);
2333 } else {
2334 l->src =
2335 strcmp (GST_ELEMENT_NAME (ret), l->src_name) == 0 ? ret : NULL;
2336 }
2337 }
2338 if (!l->src) {
2339 if (l->src_name) {
2340 SET_ERROR (error, GST_PARSE_ERROR_NO_SUCH_ELEMENT,
2341 "No element named \"%s\" - omitting link", l->src_name);
2342 } else {
2343 /* probably a missing element which we've handled already */
2344 }
2345 gst_parse_free_link (l);
2346 continue;
2347 }
2348 }
2349 if (!l->sink) {
2350 if (l->sink_name) {
2351 if (bin) {
2352 l->sink = gst_bin_get_by_name_recurse_up (bin, l->sink_name);
2353 if (l->sink)
2354 gst_object_unref (l->sink);
2355 } else {
2356 l->sink =
2357 strcmp (GST_ELEMENT_NAME (ret), l->sink_name) == 0 ? ret : NULL;
2358 }
2359 }
2360 if (!l->sink) {
2361 if (l->sink_name) {
2362 SET_ERROR (error, GST_PARSE_ERROR_NO_SUCH_ELEMENT,
2363 "No element named \"%s\" - omitting link", l->sink_name);
2364 } else {
2365 /* probably a missing element which we've handled already */
2366 }
2367 gst_parse_free_link (l);
2368 continue;
2369 }
2370 }
2371 gst_parse_perform_link (l, &g);
2372 }
2373 g_slist_free (g.links);
2375 out:
2376 #ifdef __GST_PARSE_TRACE
2377 GST_CAT_DEBUG (GST_CAT_PIPELINE,
2378 "TRACE: %u strings, %u chains and %u links left", __strings, __chains,
2379 __links);
2380 if (__strings || __chains || __links) {
2381 g_warning ("TRACE: %u strings, %u chains and %u links left", __strings,
2382 __chains, __links);
2383 }
2384 #endif /* __GST_PARSE_TRACE */
2386 return ret;
2388 error1:
2389 if (g.chain) {
2390 g_slist_foreach (g.chain->elements, (GFunc) gst_object_unref, NULL);
2391 g_slist_free (g.chain->elements);
2392 gst_parse_chain_free (g.chain);
2393 }
2395 g_slist_foreach (g.links, (GFunc) gst_parse_free_link, NULL);
2396 g_slist_free (g.links);
2398 if (error)
2399 g_assert (*error);
2400 ret = NULL;
2402 goto out;
2403 }