]> git.saurik.com Git - bison.git/blame_incremental - src/output.c
Formatting changes.
[bison.git] / src / output.c
... / ...
CommitLineData
1/* Output the generated parsing program for Bison.
2
3 Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
5
6 This file is part of Bison, the GNU Compiler Compiler.
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21#include <config.h>
22#include "system.h"
23
24#include <configmake.h>
25#include <error.h>
26#include <get-errno.h>
27#include <quotearg.h>
28#include <subpipe.h>
29#include <timevar.h>
30
31#include "complain.h"
32#include "files.h"
33#include "getargs.h"
34#include "gram.h"
35#include "muscle_tab.h"
36#include "output.h"
37#include "reader.h"
38#include "scan-code.h" /* max_left_semantic_context */
39#include "scan-skel.h"
40#include "symtab.h"
41#include "tables.h"
42
43
44static struct obstack format_obstack;
45
46
47/*-------------------------------------------------------------------.
48| Create a function NAME which associates to the muscle NAME the |
49| result of formatting the FIRST and then TABLE_DATA[BEGIN..END[ (of |
50| TYPE), and to the muscle NAME_max, the max value of the |
51| TABLE_DATA. |
52`-------------------------------------------------------------------*/
53
54
55#define GENERATE_MUSCLE_INSERT_TABLE(Name, Type) \
56 \
57static void \
58Name (char const *name, \
59 Type *table_data, \
60 Type first, \
61 int begin, \
62 int end) \
63{ \
64 Type min = first; \
65 Type max = first; \
66 long int lmin; \
67 long int lmax; \
68 int i; \
69 int j = 1; \
70 \
71 obstack_fgrow1 (&format_obstack, "%6d", first); \
72 for (i = begin; i < end; ++i) \
73 { \
74 obstack_1grow (&format_obstack, ','); \
75 if (j >= 10) \
76 { \
77 obstack_sgrow (&format_obstack, "\n "); \
78 j = 1; \
79 } \
80 else \
81 ++j; \
82 obstack_fgrow1 (&format_obstack, "%6d", table_data[i]); \
83 if (table_data[i] < min) \
84 min = table_data[i]; \
85 if (max < table_data[i]) \
86 max = table_data[i]; \
87 } \
88 obstack_1grow (&format_obstack, 0); \
89 muscle_insert (name, obstack_finish (&format_obstack)); \
90 \
91 lmin = min; \
92 lmax = max; \
93 /* Build `NAME_min' and `NAME_max' in the obstack. */ \
94 obstack_fgrow1 (&format_obstack, "%s_min", name); \
95 obstack_1grow (&format_obstack, 0); \
96 MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmin); \
97 obstack_fgrow1 (&format_obstack, "%s_max", name); \
98 obstack_1grow (&format_obstack, 0); \
99 MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmax); \
100}
101
102GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_unsigned_int_table, unsigned int)
103GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_int_table, int)
104GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_base_table, base_number)
105GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_rule_number_table, rule_number)
106GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_symbol_number_table, symbol_number)
107GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_item_number_table, item_number)
108GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table, state_number)
109
110
111/*--------------------------------------------------------------------.
112| Print to OUT a representation of STRING escaped both for C and M4. |
113`--------------------------------------------------------------------*/
114
115static void
116escaped_output (FILE *out, char const *string)
117{
118 char const *p;
119 fprintf (out, "[[");
120
121 for (p = quotearg_style (c_quoting_style, string); *p; p++)
122 switch (*p)
123 {
124 case '$': fputs ("$][", out); break;
125 case '@': fputs ("@@", out); break;
126 case '[': fputs ("@{", out); break;
127 case ']': fputs ("@}", out); break;
128 default: fputc (*p, out); break;
129 }
130
131 fprintf (out, "]]");
132}
133
134
135/*------------------------------------------------------------------.
136| Prepare the muscles related to the symbols: translate, tname, and |
137| toknum. |
138`------------------------------------------------------------------*/
139
140static void
141prepare_symbols (void)
142{
143 MUSCLE_INSERT_BOOL ("token_table", token_table_flag);
144 MUSCLE_INSERT_INT ("tokens_number", ntokens);
145 MUSCLE_INSERT_INT ("nterms_number", nvars);
146 MUSCLE_INSERT_INT ("symbols_number", nsyms);
147 MUSCLE_INSERT_INT ("undef_token_number", undeftoken->number);
148 MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number);
149
150 muscle_insert_symbol_number_table ("translate",
151 token_translations,
152 token_translations[0],
153 1, max_user_token_number + 1);
154
155 /* tname -- token names. */
156 {
157 int i;
158 /* We assume that the table will be output starting at column 2. */
159 int j = 2;
160 struct quoting_options *qo = clone_quoting_options (0);
161 set_quoting_style (qo, c_quoting_style);
162 set_quoting_flags (qo, QA_SPLIT_TRIGRAPHS);
163 for (i = 0; i < nsyms; i++)
164 {
165 char *cp = quotearg_alloc (symbols[i]->tag, -1, qo);
166 /* Width of the next token, including the two quotes, the
167 comma and the space. */
168 int width = strlen (cp) + 2;
169
170 if (j + width > 75)
171 {
172 obstack_sgrow (&format_obstack, "\n ");
173 j = 1;
174 }
175
176 if (i)
177 obstack_1grow (&format_obstack, ' ');
178 MUSCLE_OBSTACK_SGROW (&format_obstack, cp);
179 free (cp);
180 obstack_1grow (&format_obstack, ',');
181 j += width;
182 }
183 free (qo);
184 obstack_sgrow (&format_obstack, " ]b4_null[");
185
186 /* Finish table and store. */
187 obstack_1grow (&format_obstack, 0);
188 muscle_insert ("tname", obstack_finish (&format_obstack));
189 }
190
191 /* Output YYTOKNUM. */
192 {
193 int i;
194 int *values = xnmalloc (ntokens, sizeof *values);
195 for (i = 0; i < ntokens; ++i)
196 values[i] = symbols[i]->user_token_number;
197 muscle_insert_int_table ("toknum", values,
198 values[0], 1, ntokens);
199 free (values);
200 }
201}
202
203
204/*-------------------------------------------------------------.
205| Prepare the muscles related to the rules: rhs, prhs, r1, r2, |
206| rline, dprec, merger. |
207`-------------------------------------------------------------*/
208
209static void
210prepare_rules (void)
211{
212 rule_number r;
213 unsigned int i = 0;
214 item_number *rhs = xnmalloc (nritems, sizeof *rhs);
215 unsigned int *prhs = xnmalloc (nrules, sizeof *prhs);
216 unsigned int *rline = xnmalloc (nrules, sizeof *rline);
217 symbol_number *r1 = xnmalloc (nrules, sizeof *r1);
218 unsigned int *r2 = xnmalloc (nrules, sizeof *r2);
219 int *dprec = xnmalloc (nrules, sizeof *dprec);
220 int *merger = xnmalloc (nrules, sizeof *merger);
221
222 for (r = 0; r < nrules; ++r)
223 {
224 item_number *rhsp = NULL;
225 /* Index of rule R in RHS. */
226 prhs[r] = i;
227 /* RHS of the rule R. */
228 for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
229 rhs[i++] = *rhsp;
230 /* LHS of the rule R. */
231 r1[r] = rules[r].lhs->number;
232 /* Length of rule R's RHS. */
233 r2[r] = i - prhs[r];
234 /* Separator in RHS. */
235 rhs[i++] = -1;
236 /* Line where rule was defined. */
237 rline[r] = rules[r].location.start.line;
238 /* Dynamic precedence (GLR). */
239 dprec[r] = rules[r].dprec;
240 /* Merger-function index (GLR). */
241 merger[r] = rules[r].merger;
242 }
243 aver (i == nritems);
244
245 muscle_insert_item_number_table ("rhs", rhs, ritem[0], 1, nritems);
246 muscle_insert_unsigned_int_table ("prhs", prhs, 0, 0, nrules);
247 muscle_insert_unsigned_int_table ("rline", rline, 0, 0, nrules);
248 muscle_insert_symbol_number_table ("r1", r1, 0, 0, nrules);
249 muscle_insert_unsigned_int_table ("r2", r2, 0, 0, nrules);
250 muscle_insert_int_table ("dprec", dprec, 0, 0, nrules);
251 muscle_insert_int_table ("merger", merger, 0, 0, nrules);
252
253 MUSCLE_INSERT_INT ("rules_number", nrules);
254 MUSCLE_INSERT_INT ("max_left_semantic_context", max_left_semantic_context);
255
256 free (rhs);
257 free (prhs);
258 free (rline);
259 free (r1);
260 free (r2);
261 free (dprec);
262 free (merger);
263}
264
265/*--------------------------------------------.
266| Prepare the muscles related to the states. |
267`--------------------------------------------*/
268
269static void
270prepare_states (void)
271{
272 state_number i;
273 symbol_number *values = xnmalloc (nstates, sizeof *values);
274 for (i = 0; i < nstates; ++i)
275 values[i] = states[i]->accessing_symbol;
276 muscle_insert_symbol_number_table ("stos", values,
277 0, 1, nstates);
278 free (values);
279
280 MUSCLE_INSERT_INT ("last", high);
281 MUSCLE_INSERT_INT ("final_state_number", final_state->number);
282 MUSCLE_INSERT_INT ("states_number", nstates);
283}
284
285
286/*-------------------------------------------------------.
287| Compare two symbols by type-name, and then by number. |
288`-------------------------------------------------------*/
289
290int
291symbol_type_name_cmp (const symbol **lhs, const symbol **rhs)
292{
293 int res = UNIQSTR_CMP((*lhs)->type_name, (*rhs)->type_name);
294 if (res)
295 return res;
296 return (*lhs)->number - (*rhs)->number;
297}
298
299
300/*----------------------------------------------------------------.
301| Return a (malloc'ed) table of the symbols sorted by type-name. |
302`----------------------------------------------------------------*/
303
304static symbol **
305symbols_by_type_name ()
306{
307 typedef int (*qcmp_type) (const void *, const void *);
308 symbol **res = xmemdup (symbols, nsyms * sizeof *res);
309 qsort (res, nsyms, sizeof *res, (qcmp_type) &symbol_type_name_cmp);
310 return res;
311}
312
313
314/*------------------------------------------------------------------.
315| Define b4_type_names, which is a list of (lists of the numbers of |
316| symbols with same type-name). |
317`------------------------------------------------------------------*/
318
319static void
320type_names_output (FILE *out)
321{
322 int i;
323 const char *isep = "";
324 symbol **syms = symbols_by_type_name ();
325 fputs ("m4_define([b4_type_names],\n[", out);
326 for (i = 0; i < nsyms; )
327 if (syms[i]->type_name)
328 {
329 int j;
330 const char *jsep = "";
331 fprintf (out, "%s[", isep);
332 isep = ",\n";
333 for (j = i; j < nsyms; ++j)
334 {
335 if (syms[i]->type_name != syms[j]->type_name)
336 break;
337 fprintf (out, "%s%d", jsep, syms[j]->number);
338 jsep = ", ";
339 }
340 fputs ("]", out);
341 i = j;
342 }
343 else
344 ++i;
345 fputs ("])\n\n", out);
346 free (syms);
347}
348
349
350/*-------------------------------------.
351| The list of all the symbol numbers. |
352`-------------------------------------*/
353
354static void
355symbol_numbers_output (FILE *out)
356{
357 int i;
358 fputs ("m4_define([b4_symbol_numbers],\n[", out);
359 for (i = 0; i < nsyms; ++i)
360 fprintf (out, "%s[%d]", i ? ", " : "", i);
361 fputs ("])\n\n", out);
362}
363
364
365/*---------------------------------.
366| Output the user actions to OUT. |
367`---------------------------------*/
368
369static void
370user_actions_output (FILE *out)
371{
372 rule_number r;
373
374 fputs ("m4_define([b4_actions], \n[", out);
375 for (r = 0; r < nrules; ++r)
376 if (rules[r].action)
377 {
378 fprintf (out, "b4_case(%d, [b4_syncline(%d, ", r + 1,
379 rules[r].action_location.start.line);
380 escaped_output (out, rules[r].action_location.start.file);
381 fprintf (out, ")\n[ %s]])\n\n", rules[r].action);
382 }
383 fputs ("])\n\n", out);
384}
385
386/*------------------------------------.
387| Output the merge functions to OUT. |
388`------------------------------------*/
389
390static void
391merger_output (FILE *out)
392{
393 int n;
394 merger_list* p;
395
396 fputs ("m4_define([b4_mergers], \n[[", out);
397 for (n = 1, p = merge_functions; p != NULL; n += 1, p = p->next)
398 {
399 if (p->type[0] == '\0')
400 fprintf (out, " case %d: *yy0 = %s (*yy0, *yy1); break;\n",
401 n, p->name);
402 else
403 fprintf (out, " case %d: yy0->%s = %s (*yy0, *yy1); break;\n",
404 n, p->type, p->name);
405 }
406 fputs ("]])\n\n", out);
407}
408
409
410/*---------------------------------------.
411| Output the symbol definitions to OUT. |
412`---------------------------------------*/
413
414static void
415symbol_definitions_output (FILE *out)
416{
417 int i;
418 for (i = 0; i < nsyms; ++i)
419 {
420 symbol *sym = symbols[i];
421 const char *key;
422
423#define SET_KEY(Entry) \
424 obstack_fgrow2 (&format_obstack, "symbol(%d, %s)", i, Entry); \
425 obstack_1grow (&format_obstack, 0); \
426 key = obstack_finish (&format_obstack);
427
428 SET_KEY("tag");
429 MUSCLE_INSERT_STRING (key, sym->tag);
430
431 SET_KEY("user_number");
432 MUSCLE_INSERT_INT (key, sym->user_token_number);
433
434 SET_KEY("number");
435 MUSCLE_INSERT_INT (key, sym->number);
436
437 SET_KEY("type_name");
438 MUSCLE_INSERT_STRING (key, sym->type_name ? sym->type_name : "");
439
440#undef SET_KEY
441 }
442}
443
444
445/*--------------------------------------.
446| Output the tokens definition to OUT. |
447`--------------------------------------*/
448
449static void
450token_definitions_output (FILE *out)
451{
452 int i;
453 char const *sep = "";
454
455 fputs ("m4_define([b4_tokens], \n[", out);
456 for (i = 0; i < ntokens; ++i)
457 {
458 symbol *sym = symbols[i];
459 int number = sym->user_token_number;
460
461 /* At this stage, if there are literal aliases, they are part of
462 SYMBOLS, so we should not find symbols which are the aliases
463 here. */
464 aver (number != USER_NUMBER_ALIAS);
465
466 /* Skip error token. */
467 if (sym == errtoken)
468 continue;
469
470 /* If this string has an alias, then it is necessarily the alias
471 which is to be output. */
472 if (sym->alias)
473 sym = sym->alias;
474
475 /* Don't output literal chars or strings (when defined only as a
476 string). Note that must be done after the alias resolution:
477 think about `%token 'f' "f"'. */
478 if (sym->tag[0] == '\'' || sym->tag[0] == '\"')
479 continue;
480
481 /* Don't #define nonliteral tokens whose names contain periods
482 or '$' (as does the default value of the EOF token). */
483 if (strchr (sym->tag, '.') || strchr (sym->tag, '$'))
484 continue;
485
486 fprintf (out, "%s[[[%s]], %d]",
487 sep, sym->tag, number);
488 sep = ",\n";
489 }
490 fputs ("])\n\n", out);
491}
492
493
494/*---------------------------------------------------.
495| Output the symbol destructors or printers to OUT. |
496`---------------------------------------------------*/
497
498static void
499symbol_code_props_output (FILE *out, char const *what,
500 code_props const *(*get)(symbol const *))
501{
502 int i;
503 char const *sep = "";
504
505 fputs ("m4_define([b4_symbol_", out);
506 fputs (what, out);
507 fputs ("], \n[", out);
508 for (i = 0; i < nsyms; ++i)
509 {
510 symbol *sym = symbols[i];
511 char const *code = (*get) (sym)->code;
512 if (code)
513 {
514 location loc = (*get) (sym)->location;
515 /* Filename, lineno,
516 Symbol-name, Symbol-number,
517 code, optional typename. */
518 fprintf (out, "%s[", sep);
519 sep = ",\n";
520 escaped_output (out, loc.start.file);
521 fprintf (out, ", %d, ", loc.start.line);
522 escaped_output (out, sym->tag);
523 fprintf (out, ", %d, [[%s]]", sym->number, code);
524 if (sym->type_name)
525 fprintf (out, ", [[%s]]", sym->type_name);
526 fputc (']', out);
527 }
528 }
529 fputs ("])\n\n", out);
530}
531
532
533static void
534prepare_actions (void)
535{
536 /* Figure out the actions for the specified state, indexed by
537 lookahead token type. */
538
539 muscle_insert_rule_number_table ("defact", yydefact,
540 yydefact[0], 1, nstates);
541
542 /* Figure out what to do after reducing with each rule, depending on
543 the saved state from before the beginning of parsing the data
544 that matched this rule. */
545 muscle_insert_state_number_table ("defgoto", yydefgoto,
546 yydefgoto[0], 1, nsyms - ntokens);
547
548
549 /* Output PACT. */
550 muscle_insert_base_table ("pact", base,
551 base[0], 1, nstates);
552 MUSCLE_INSERT_INT ("pact_ninf", base_ninf);
553
554 /* Output PGOTO. */
555 muscle_insert_base_table ("pgoto", base,
556 base[nstates], nstates + 1, nvectors);
557
558 muscle_insert_base_table ("table", table,
559 table[0], 1, high + 1);
560 MUSCLE_INSERT_INT ("table_ninf", table_ninf);
561
562 muscle_insert_base_table ("check", check,
563 check[0], 1, high + 1);
564
565 /* GLR parsing slightly modifies YYTABLE and YYCHECK (and thus
566 YYPACT) so that in states with unresolved conflicts, the default
567 reduction is not used in the conflicted entries, so that there is
568 a place to put a conflict pointer.
569
570 This means that YYCONFLP and YYCONFL are nonsense for a non-GLR
571 parser, so we could avoid accidents by not writing them out in
572 that case. Nevertheless, it seems even better to be able to use
573 the GLR skeletons even without the non-deterministic tables. */
574 muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table,
575 conflict_table[0], 1, high + 1);
576 muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list,
577 0, 1, conflict_list_cnt);
578}
579
580
581/*--------------------------------------------.
582| Output the definitions of all the muscles. |
583`--------------------------------------------*/
584
585static void
586muscles_output (FILE *out)
587{
588 fputs ("m4_init()\n", out);
589 merger_output (out);
590 symbol_code_props_output (out, "destructors", &symbol_destructor_get);
591 symbol_code_props_output (out, "printers", &symbol_printer_get);
592 symbol_definitions_output (out);
593 symbol_numbers_output (out);
594 token_definitions_output (out);
595 type_names_output (out);
596 user_actions_output (out);
597 // Must be last.
598 muscles_m4_output (out);
599}
600\f
601/*---------------------------.
602| Call the skeleton parser. |
603`---------------------------*/
604
605static void
606output_skeleton (void)
607{
608 FILE *in;
609 int filter_fd[2];
610 char const *argv[9];
611 pid_t pid;
612
613 /* Compute the names of the package data dir and skeleton files. */
614 char const m4sugar[] = "m4sugar/m4sugar.m4";
615 char const m4bison[] = "bison.m4";
616 char *full_m4sugar;
617 char *full_m4bison;
618 char *full_skeleton;
619 char const *p;
620 char const *m4 = (p = getenv ("M4")) ? p : M4;
621 char const *pkgdatadir = compute_pkgdatadir ();
622 size_t skeleton_size = strlen (skeleton) + 1;
623 size_t pkgdatadirlen = strlen (pkgdatadir);
624 while (pkgdatadirlen && pkgdatadir[pkgdatadirlen - 1] == '/')
625 pkgdatadirlen--;
626 full_skeleton = xmalloc (pkgdatadirlen + 1
627 + (skeleton_size < sizeof m4sugar
628 ? sizeof m4sugar : skeleton_size));
629 strncpy (full_skeleton, pkgdatadir, pkgdatadirlen);
630 full_skeleton[pkgdatadirlen] = '/';
631 strcpy (full_skeleton + pkgdatadirlen + 1, m4sugar);
632 full_m4sugar = xstrdup (full_skeleton);
633 strcpy (full_skeleton + pkgdatadirlen + 1, m4bison);
634 full_m4bison = xstrdup (full_skeleton);
635 if (strchr (skeleton, '/'))
636 strcpy (full_skeleton, skeleton);
637 else
638 strcpy (full_skeleton + pkgdatadirlen + 1, skeleton);
639
640 /* Test whether m4sugar.m4 is readable, to check for proper
641 installation. A faulty installation can cause deadlock, so a
642 cheap sanity check is worthwhile. */
643 xfclose (xfopen (full_m4sugar, "r"));
644
645 /* Create an m4 subprocess connected to us via two pipes. */
646
647 if (trace_flag & trace_tools)
648 fprintf (stderr, "running: %s %s - %s %s\n",
649 m4, full_m4sugar, full_m4bison, full_skeleton);
650
651 /* Some future version of GNU M4 (most likely 1.6) may treat the -dV in a
652 position-dependent manner. Keep it as the first argument so that all
653 files are traced.
654
655 See the thread starting at
656 <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html>
657 for details. */
658 {
659 int i = 0;
660 argv[i++] = m4;
661 argv[i++] = "-I";
662 argv[i++] = pkgdatadir;
663 if (trace_flag & trace_m4)
664 argv[i++] = "-dV";
665 argv[i++] = full_m4sugar;
666 argv[i++] = "-";
667 argv[i++] = full_m4bison;
668 argv[i++] = full_skeleton;
669 argv[i++] = NULL;
670 }
671 /* When POSIXLY_CORRECT is set, some future versions of GNU M4 (most likely
672 2.0) may drop some of the GNU extensions that Bison's skeletons depend
673 upon. So that the next release of Bison is forward compatible with those
674 future versions of GNU M4, we unset POSIXLY_CORRECT here.
675
676 FIXME: A user might set POSIXLY_CORRECT to affect processes run from
677 macros like m4_syscmd in a custom skeleton. For now, Bison makes no
678 promises about the behavior of custom skeletons, so this scenario is not a
679 concern. However, we eventually want to eliminate this shortcoming. The
680 next release of GNU M4 (1.4.12 or 1.6) will accept the -g command-line
681 option as a no-op, and later releases will accept it to indicate that
682 POSIXLY_CORRECT should be ignored. Once the GNU M4 versions that accept
683 -g are pervasive, Bison should use -g instead of unsetting
684 POSIXLY_CORRECT.
685
686 See the thread starting at
687 <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html>
688 for details. */
689 unsetenv ("POSIXLY_CORRECT");
690 init_subpipe ();
691 pid = create_subpipe (argv, filter_fd);
692 free (full_m4sugar);
693 free (full_m4bison);
694 free (full_skeleton);
695
696 if (trace_flag & trace_muscles)
697 muscles_output (stderr);
698 {
699 FILE *out = fdopen (filter_fd[0], "w");
700 if (! out)
701 error (EXIT_FAILURE, get_errno (),
702 "fdopen");
703 muscles_output (out);
704 xfclose (out);
705 }
706
707 /* Read and process m4's output. */
708 timevar_push (TV_M4);
709 end_of_output_subpipe (pid, filter_fd);
710 in = fdopen (filter_fd[1], "r");
711 if (! in)
712 error (EXIT_FAILURE, get_errno (),
713 "fdopen");
714 scan_skel (in);
715 xfclose (in);
716 reap_subpipe (pid, m4);
717 timevar_pop (TV_M4);
718}
719
720static void
721prepare (void)
722{
723 /* BISON_USE_PUSH_FOR_PULL is for the test suite and should not be documented
724 for the user. */
725 char const *use_push_for_pull_env = getenv ("BISON_USE_PUSH_FOR_PULL");
726 bool use_push_for_pull_flag = false;
727 if (use_push_for_pull_env != NULL
728 && use_push_for_pull_env[0] != '\0'
729 && 0 != strcmp (use_push_for_pull_env, "0"))
730 use_push_for_pull_flag = true;
731
732 /* Flags. */
733 MUSCLE_INSERT_BOOL ("debug_flag", debug_flag);
734 MUSCLE_INSERT_BOOL ("defines_flag", defines_flag);
735 MUSCLE_INSERT_BOOL ("error_verbose_flag", error_verbose);
736 MUSCLE_INSERT_BOOL ("glr_flag", glr_parser);
737 MUSCLE_INSERT_BOOL ("locations_flag", locations_flag);
738 MUSCLE_INSERT_BOOL ("nondeterministic_flag", nondeterministic_parser);
739 MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag);
740 MUSCLE_INSERT_BOOL ("tag_seen_flag", tag_seen);
741 MUSCLE_INSERT_BOOL ("use_push_for_pull_flag", use_push_for_pull_flag);
742 MUSCLE_INSERT_BOOL ("yacc_flag", yacc_flag);
743
744 /* File names. */
745 if (spec_name_prefix)
746 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix);
747
748 MUSCLE_INSERT_STRING ("file_name_all_but_ext", all_but_ext);
749
750#define DEFINE(Name) MUSCLE_INSERT_STRING (#Name, Name ? Name : "")
751 DEFINE (dir_prefix);
752 DEFINE (parser_file_name);
753 DEFINE (spec_defines_file);
754 DEFINE (spec_file_prefix);
755 DEFINE (spec_graph_file);
756 DEFINE (spec_name_prefix);
757 DEFINE (spec_outfile);
758 DEFINE (spec_verbose_file);
759#undef DEFINE
760
761 /* Find the right skeleton file, and add muscles about the skeletons. */
762 if (skeleton)
763 MUSCLE_INSERT_C_STRING ("skeleton", skeleton);
764 else
765 skeleton = language->skeleton;
766
767 /* About the skeletons. */
768 {
769 /* b4_pkgdatadir is used inside m4_include in the skeletons, so digraphs
770 would never be expanded. Hopefully no one has M4-special characters in
771 his Bison installation path. */
772 MUSCLE_INSERT_STRING_RAW ("pkgdatadir", compute_pkgdatadir ());
773 }
774}
775
776
777/*----------------------------------------------------------.
778| Output the parsing tables and the parser code to ftable. |
779`----------------------------------------------------------*/
780
781void
782output (void)
783{
784 obstack_init (&format_obstack);
785
786 prepare_symbols ();
787 prepare_rules ();
788 prepare_states ();
789 prepare_actions ();
790
791 prepare ();
792
793 /* Process the selected skeleton file. */
794 output_skeleton ();
795
796 obstack_free (&format_obstack, NULL);
797}
798
799char const *
800compute_pkgdatadir (void)
801{
802 char const *pkgdatadir = getenv ("BISON_PKGDATADIR");
803 return pkgdatadir ? pkgdatadir : PKGDATADIR;
804}