#!/usr/bin/perl -w
use strict;

die("usage: $0 <package-name> <prefix-file-name> <source-file-name>\n") unless
	@ARGV == 3;
my ($pkgTag, $pfxName, $fname) = @ARGV;

my $prefix = `cat $pfxName` or die("cannot load prefix from $pfxName: $!, stopped");

my %Guards = (); # generated guards

open(IF, "<$fname") or die("cannot open $fname: $!, stopped");
my $didPrefix = 0; 
my $didGuard = 0; 
my $skipOne = 0;
while (<IF>) {
	if ($skipOne) {
		$skipOne = 0;
		next;
	}

	if (!$didPrefix && /^\#/) {
		print($prefix);
		$didPrefix = 1;
	}

	next unless $didPrefix;

	if ($fname =~ /\.h$/ && !$didGuard) {
		if (/^#ifndef .*_H/) {
			$didGuard = 1;
			my $guard = &calcGuard($pkgTag, $fname);

			die("Guard collision for $guard, stopped") if
				defined $Guards{$guard};
			$Guards{$guard} = $fname;

			printf("#ifndef %s\n", $guard);
			printf("#define %s\n", $guard);
			$skipOne = 1;
			next;
		} 
		elsif (/^#pragma\s/) {
			$didGuard = 1;
			print($_);
			next;
		}
	}

	print($_);
}
close(IF);

if ($fname =~ /\.h$/) {
	die("failed to guard .h header $fname, stopped") unless $didGuard;
}

die("failed to set prefix in $fname, stopped") unless $didPrefix;

exit(0);


sub calcGuard {
	my ($pkgName, $fileName) = @_;

	$fileName =~ s@/src/@/@; # remove /src/ path, as a common case
	$fileName =~ s@^(\./|/)@@; # remove leading ./ or /
	my $guard = $pkgName . '__' . $fileName;

	$guard =~ s/[^A-z_0-9]/_/g; # extension, path components, other
	$guard =~ s/([a-z])([A-Z])/$1_$2/g; # between case changes: fooBar
	return uc($guard);
}
