#!/usr/bin/perl
#
# $Id$
#
# Format output generated by bison
#
# Usage:
#  bison -b brql_parser -p brql_parser_ -d -v brql_parser.y
#  perl fix-bison brql_parser.tab.c > $tmp
#  mv $tmp brql_parser.tab.c
#
# Copyright (C) 2004-2009, David Beckett http://www.dajobe.org/
# Copyright (C) 2004, University of Bristol, UK http://www.bristol.ac.uk/
#

my $seen_yyerrlab1=0;
my $line_offset=1; # #line directives always refer to the NEXT line
while(<>) {
  # HACK: Pass YYPARSE_PARAM* to %destructors
  s/(yydestruct\s*\()const/$1void *YYPARSE_PARAM, const/; # yydestruct() definition sig 1
  if(/(yydestruct\s*\()yymsg(.*)$/) { # yydestruct() defintion sig 2
    print "$1YYPARSE_PARAM, yymsg$2\n    void *YYPARSE_PARAM;\n";
    $line_offset++; # added a line
    next;
  }
  s/(yydestruct\s*\()(".*)$/$1YYPARSE_PARAM, $2/; # yydestruct() calls

  # Remove code that causes a warning
  if(/Suppress GCC warning that yyerrlab1/) {
    do {
      $_=<>;
      $line_offset--; # skipped a line
    } while(!/^\#endif/);
    $line_offset--; # skipped a line
    next;
  }

  $seen_yyerrlab1=1 if /goto yyerrlab1/;

  s/^yyerrlab1:// unless $seen_yyerrlab1;

  # Do not use macro name for a temporary variable
  s/unsigned int yylineno = /unsigned int yylineno_tmp = /;
  s/yyrule - 1, yylineno\)/yyrule - 1, yylineno_tmp\)/;

  # Do not (re)define prototypes that the system did better
  if(m%^void \*malloc\s*\(%) {
    $line_offset--; # skipped a line
    next;
  }
  if(m%^void free\s*\(%) {
    $line_offset--; # skipped a line
    next; 
  }

  # Suppress warnings about empty declarations
  s/(^static int .*_init_globals.*);$/$1/;

  # Fixup pending filename renaming, see above.
  # Fix line numbers.
  my $line=$. +$line_offset;
  s/^(\#line) \d+ (.*)\.tab\.c/$1 $line $2.c/;

  print;
}
