#------------
# this perl script invokes a devstudio build
# on specified workspace and configuration
#-------
# tested on devstudio 5.0
# assumes devstudio logging is turned on
#------------

require 5.005;

# preconditions:
#
# NT 4.0 and perl 5.005 or better.
#
# blame: steve hardy
# shardy@@differentchairs.com


# paranoid mode: make sure we have a temp directory
if (!$ENV{TEMP})
  {
  $ENV{TEMP} = "C:\\TEMP";
  }
my $tempdir  = $ENV{TEMP};
system("if not exist $tempdir md $tempdir");


my $logfname = "$tempdir\\build100.log";
while ( -e $logfname )
  {
  $logfname = sprintf("$tempdir\\build%d.log", int(rand(899)) + 100); #100..999
  }


# -- Begin MAIN

my $cfgname      = "MakeAll - Win32 Release"; #default configuration to build
my $wsfilespec   = $ARGV[0];
my $buildsuccess = 0;

my $argc = @ARGV;
my $help = 0;

if ($argc>2 || $argc<1)
	{
	$help = 1;
	}
elsif ($argc==2)
	{
	$cfgname = $ARGV[1];
	}

if ($help)
	{
	help();
	}
else
	{
	# launch devstudio build
	use OLE;
	&build_proj( $wsfilespec, $cfgname);
	system("type $logfname");

	my $dswlogname = getlogspec($wsfilespec, $cfgname);
	if (0==chkresults( $dswlogname ))
		{
		print "\nBuild ok\n";
		$buildsuccess = 1;
		}
	else
		{
		print "\nBuild error(s) detected\n";
		}
	unlink($logfname);
	}
!$buildsuccess;

# -- End MAIN



#------------
# display usage statement
#------------
sub help
	{
	print "\nusage: build.pl WorkspaceFilespec [\"configuration to build\"]\n";
	print "\n        default configuration is \"MakeAll - Win32 Release\"\n\n";
	}


#------------
# builds specified projects w/ the dsw file using OLE automation interface
#------------
sub build_proj
	{
	my ($workspace_file, $cfg_line) = @_;
	my ($wsfile) = $workspace_file;
	my $app = CreateObject OLE "MSDev.Application";
	$app->{'Visible'} = 1;
	printlog( "Opening $workspace_file\n");
	$app->Documents->Open($workspace_file);

	my $foundcfg = 0;
	my $proj_count = $app->Projects->Count;

	for ($pnum = 1; $pnum <= $proj_count; $pnum++)
		{
		my $proj_config = $app->Projects($pnum)->Configurations;

		my $config_count = $proj_config->Count;

		for ($num = 1; $num <= $config_count; $num++)
			{
			my $config = $app->Projects($pnum)->Configurations($num);

			if ($config->Name =~ /$cfg_line$/i)
				{
				$foundcfg = 1;
				printlog( "Building ".$config->Name."\n");

				# extract and trim everything before the '-'
				my $prjname = $config->Name;
				$prjname =~ s/^(.*?) -.*$/$1/;
				$app->Build($config);
				}
			}
		}
	if (!$foundcfg)
		{
		printlog( "Configuration [$cfg_line] not found" );
		}
	$app->Documents->CloseAll;
	$app->Quit;
	}

#------------
# scan logfile for build error indications
#------------
sub chkresults
	{
	my $result = 0;

	my ($logfile) = @_;

	if ( open(LOGFILE, "<$logfile") )
		{
		LINE:
		while (<LOGFILE>) # check for error conditions...
			{
			if (/ error/i)
				{
				if ( !/^0 error| 0 error/ ) #ignore "0 errors" msgs
					{
					$result = 5;
					last LINE;
					}
				}
			elsif (/cannot/i)
				{
				$result = 2;
				last LINE;
				}
			elsif (/recognize/i)
				{
				$result = 3;
				last LINE;
				}
			elsif (/missing/i)
				{
				$result = 4;
				last LINE;
				}
			}
		close(LOGFILE);
		}
	else
		{
		$result = 1;
		}

	if ($result>1)
		{
		system("copy \"$logfile\" \"$resultfile\" >nul");
		}
	elsif ($result==1)
		{
		system(" echo No build log file found> \"$resultfile\"  ");
		}

	return $result;
	}

#------------
# get qualified filespec to devstudio log (uses undocumented vc 5.0 info)
#------------
sub getlogspec
	{
	# the logfile resides in the same directory as the project being built, and
	# is named the same. So the log for
	# the MakeAll project is in the same directory as MakeAll.dsp
	# and is named MakeAll.plg
	# The .dsw file indicates where to find the .dsp file.

	my ($workspace_file, $cfg_line) = @_;

	my $logspec;
	my $prjname = $cfg_line;
	$prjname =~ s/^(.*?) -.*$/$1/;

	if ( open(WSFILE, "<$workspace_file") )
		{
		$workspace_file =~ s/(.*[:\\]).*/$1/;
		if ( index($workspace_file, ".dsw") >= 0 ) # no dirspec?
			{
			$workspace_file = "";
			}
		WSLINE:
		while ( <WSFILE> )
			{
			chomp $_;

			# this line relies on the undocumented dsw file format...
			# example: Project: "np32"=.\sf95\atmnp32\ATMNP32.dsp - Package Owner=<4>
			if ( s/[^"]*"$prjname"=(.*\\[^ ]*)\.dsp.*/$1/i) #(.\sf95\atmnp32\ATMNP32)
				{
				$logspec = "$workspace_file$1.plg";
				last WSLINE;
				}
			}
		close(WSFILE);
		}
	return $logspec;
	}


#------------
# write message to logfile and STDOUT
#------------
sub printlog
	{
	if ($printlog eq "")
		{
		open(PRINTLOG_FILE, ">$logfname") || die "Can't create $logfname";
		$printlog = 1;
		}
	print @_;
	print PRINTLOG_FILE @_;
	}