+
+ return rrc_count;
+}
+
+/*--------------------------------------------------------------.
+| Return a human readable string which reports shift/reduce and |
+| reduce/reduce conflict numbers (SRC_NUM, RRC_NUM). |
+`--------------------------------------------------------------*/
+
+static const char *
+conflict_report (int src_num, int rrc_num)
+{
+ static char res[4096];
+ char *cp = res;
+
+ if (src_num >= 1)
+ {
+ sprintf (cp, ngettext ("%d shift/reduce conflict",
+ "%d shift/reduce conflicts", src_num), src_num);
+ cp += strlen (cp);
+ }
+
+ if (src_num > 0 && rrc_num > 0)
+ {
+ sprintf (cp, " %s ", _("and"));
+ cp += strlen (cp);
+ }
+
+ if (rrc_num >= 1)
+ {
+ sprintf (cp, ngettext ("%d reduce/reduce conflict",
+ "%d reduce/reduce conflicts", rrc_num), rrc_num);
+ cp += strlen (cp);
+ }
+
+ *cp++ = '.';
+ *cp++ = '\n';
+ *cp++ = '\0';
+
+ return res;
+}
+
+
+/*-----------------------------------------------------------.
+| Output the detailed description of states with conflicts. |
+`-----------------------------------------------------------*/
+
+void
+conflicts_output (FILE *out)
+{
+ bool printed_sth = FALSE;
+ int i;
+ for (i = 0; i < nstates; i++)
+ if (conflicts[i])
+ {
+ fprintf (out, _("State %d contains "), i);
+ fputs (conflict_report (count_sr_conflicts (i),
+ count_rr_conflicts (i)), out);
+ printed_sth = TRUE;
+ }
+ if (printed_sth)
+ fputs ("\n\n", out);
+}
+
+
+/*------------------------------------------.
+| Reporting the total number of conflicts. |
+`------------------------------------------*/
+
+void
+conflicts_print (void)
+{
+ int i;
+
+ /* Is the number of SR conflicts OK? Either EXPECTED_CONFLICTS is
+ not set, and then we want 0 SR, or else it is specified, in which
+ case we want equality. */
+ int src_ok = 0;
+
+ int src_total = 0;
+ int rrc_total = 0;
+
+ /* Conflicts by state. */
+ for (i = 0; i < nstates; i++)
+ if (conflicts[i])
+ {
+ src_total += count_sr_conflicts (i);
+ rrc_total += count_rr_conflicts (i);
+ }
+
+ src_ok = src_total == (expected_conflicts == -1 ? 0 : expected_conflicts);
+
+ /* If there are no RR conflicts, and as many SR conflicts as
+ expected, then there is nothing to report. */
+ if (!rrc_total && src_ok)
+ return;
+
+ /* Report the total number of conflicts on STDERR. */
+ if (yacc_flag)
+ {
+ /* If invoked with `--yacc', use the output format specified by
+ POSIX. */
+ fprintf (stderr, _("conflicts: "));
+ if (src_total > 0)
+ fprintf (stderr, _(" %d shift/reduce"), src_total);
+ if (src_total > 0 && rrc_total > 0)
+ fprintf (stderr, ",");
+ if (rrc_total > 0)
+ fprintf (stderr, _(" %d reduce/reduce"), rrc_total);
+ putc ('\n', stderr);
+ }
+ else
+ {
+ fprintf (stderr, _("%s contains "), infile);
+ fputs (conflict_report (src_total, rrc_total), stderr);
+ }
+
+ if (expected_conflicts != -1 && !src_ok)
+ {
+ complain_message_count++;
+ fprintf (stderr, ngettext ("expected %d shift/reduce conflict\n",
+ "expected %d shift/reduce conflicts\n",
+ expected_conflicts),
+ expected_conflicts);
+ }