#!/usr/bin/perl -w
use strict;
use warnings;
use diagnostics;
use Getopt::Std;

my $HELP = "Usage: $0 [FILE]...
	Parses [FILE], outputing the result to stdout.";

sub usage {
	print "@_\n";
	exit;
}

our($opt_h, $opt_v, $title, $body, $indent, $idpath, $inblock);

getopts("hv") or usage($HELP);
$opt_v and usage("Copyleft (c) 2006, Russ Rowan (See `COPYING')");
usage($HELP) if $opt_h or @ARGV < 1;

sub put_section {
	if ($title) {
		print "\n$title\n";
		$_ = $title;
		s/[^-]/-/g;
		print "$_\n" if not $indent;
	}
	if ($body) {
		$_ = $body;
		s/#newline#/$indent/g;
		print "$_\n";
	}
	$title = $body = undef;
}

$idpath = $title = $body = "";
while (<>)
{
	my $end = s/\s*\*+\//\n/ ? 'yes' : undef;

	if ($end and /[^=]*[\s*](\w+)[\s:,;].*\/\*:\s*(.*)/) {
		# Implicit id for enum values and struct members.
		print "\nid:[$idpath$1]::\n\t$2\n";

	} elsif ($inblock) {
		# Redo the indentation, preserve empty lines.
		s/^(\s|\*)*//;
		s/^$/\n/;
		$body .= "#newline#" . $_;

	} elsif (s/\s*\/\*\*+\s*(.*)/$1/) {
		# Found magic header; flush, record title and set indentation.
		put_section;
		$title   = "$1";
		$indent  = /::/ ? "\t" : "";

	} else {
		next if not ($title or $body) or /^\s$/;

		my $orig_title = $title;

		if (not /^#define\s/) {
			while (not /(struct|enum|typedef|[^=])*[\s*](\w+).*[\[:,;{]/) {
				$_ .= <>;
			}
		}

		if (/struct\s+(\w+)\s*{/) {
			$title = "struct:$1" . "[$title]";
			$idpath = "$1.";

		} elsif (/enum\s+(\w+)\s*{/) {
			$title = "enum:$1" . "[$title]";
			$idpath = "";

		} elsif (/#define\s+(\w+)[(]/) {
			$title = "func:$1" . "[$title]";
			$idpath = "";

		} elsif (/#define\s+(\w+)/) {
			$title = "macro:$1" . "[$title]";
			$idpath = "";

		} else {
			if (/typedef/) {
				if (/.*\(\*(\w+)\)\(/) {
					$title = "typedef:$1" . "[$title]";
				} elsif (/typedef.*\s(\w+);/) {
					$title = "typedef:$1" . "[$title]";
				}
				$idpath = "";
			} else {
				if (/.*[\s*](\w+)\(/) {
					$title = "func:$1" . "[$title]";
					$idpath = "";
				} elsif (/.*\(\*(\w+)\)\(/) {
					$body = "#newline#" . $title if not $body;
					$title = "id:[$idpath$1]::";
					$indent = "\t";
				} elsif (/[^=]*[\s*](\w+)[\[\s,:;]/) {
					$body = "#newline#" . $title if not $body;
					$title = "id:[$idpath$1]::";
					$indent = "\t";
				}
			}
		}
		put_section if $orig_title ne $title;
		next;
	}

	$inblock = $end ? undef : 'yes';
}