#!c:\perl -w
# NAME: checkifd.pl
# AIM: To check the openning and closing of #if #ifdef #ifndef #else #endif blocks in a C/C++ file
# 3/13/2009 - geoff mclane - http://geoffair.net/mperl/
use strict;
use warnings;
my $BN = $0;

my @warnings = ();

# debug
my $dbg1 = 1;	# use a default name

sub prt($) {
	print shift;
}

sub prtw($) {
	my ($t) = shift;
	prt($t);
	$t =~ s/\n$//;
	push @warnings, $t;
}

sub process_file($) {
	my ($fil) = shift;
	my (@lines, $lncnt, $line, $itxt, $lnnum, $dep, $ln);
	my @depth = ();
	if (open INF, "<$fil") {
		@lines = <INF>;
		$lncnt = scalar @lines;
		prt( "$BN: Processing $lncnt lines, from $fil...\n" );
		$lnnum = 0;
		foreach $line (@lines) {
			chomp $line;
			$lnnum++;
			$dep = scalar @depth;
			$ln = "$lnnum:$dep";
			if ($line =~ /^\s*#\s*if.*\s+(.+)$/) {
				$itxt = $1;
				prt( "$ln: $line ($itxt)\n" );
				push(@depth, "$ln: $itxt");
			} elsif ($line =~ /^\s*#\s*else\s*(.*)$/) {
				$itxt = '';
				$itxt = $1 if ($1);
				prt( "$ln: $line ($itxt)\n" );
	        } elsif ($line =~ /^\s*#\s*endif/) {
				if (@depth) {
					$itxt = pop @depth;
					$dep = scalar @depth;
					$ln = "$lnnum:$dep";
					prt( "$ln: $line ($itxt)\n" );
				} else {
					$itxt = "***WARNING*** NO DEPTH!";
					prtw( "$ln: $line ($itxt)\n" );
				}
			}
		}
	} else {
		prt( "$BN: ERROR: failed to open $fil!\n" );
	}
}


my $in_file ='';
if ($dbg1) {
	$in_file = 'C:\FG\30\pthreads\ptw32_InterlockedCompareExchange.c';
}
if (@ARGV) {
	$in_file = shift @ARGV;
	if ( ! -f $in_file ) {
		die "$BN: Can not locate [$in_file]\n";
	}
}
if (length($in_file)==0) {
	die "$BN: Give input file to check...\n";
}

process_file($in_file);
if (@warnings) {
	prt( "Got ".scalar @warnings." warnings...\n" );
	foreach my $w (@warnings) {
		prt( "$w\n" );
	}
}
exit 0;
# eof - checkifd.pl
