#!/afs/sipb/project/perldev/p -w -0777
# extract function declarations (and generate prototypes)

use strict;

local $_ = <>;  # this is the entire file, because of -0777

# remove comments; make sure Perl isn't greedy
s@/\*+(:?[^*]|\*+[^/*])*\*+/@@gs;

# remove cpp directives
s@^\s*\#.*$@@gm;

# munge strings so we can munge blocks without being affected by {'s in ""s
# [NB: strings must not contain unbalanced comment delimiters]
s@\"(:?[^\\\"]|\\.)*\"@""@gs;
s@\'(:?[^\\]|\\.)\'@''@gs;

# munge blocks
1 while s@\{(:?[^{}]|\{\})+\}@{}@gs;

# eat whitespace
s/\s+/ /g;

# split into chunks
my @frags = split /(\{\}|;)/;
my @chunks = ();

my $last = pop @frags;
die "unexpected last chunk '$last'\nfound" unless ($last =~ /^\s+/);

while (@frags) {
  push(@chunks, shift(@frags) . shift(@frags));
}

# print out relevant chunks
my (@vars, @funs);

foreach (@chunks) {
  # print "[[$_]]\n";
  /^\s*(static\s+)?([^=(){}]+\([^=(){}]*\))\s*\{\}\s*$/ && !$1
    && push(@funs, "$2;\n");
  /^\s*(static\s+)?([^=(){}]*[^=(){}\s])\s*(:?=.*)?;\s*$/ && !$1
    && push(@vars, "extern $2;\n");
}

print "/* variables */\n", @vars, "\n/* functions */\n", @funs;
