<commit_before>package Install;

#
# Package that provides 'make install' functionality for msvc builds
#
# src/tools/msvc/Install.pm
#
use strict;
use warnings;
use Carp;
use File::Basename;
use File::Copy;
use File::Find ();

use Exporter;
our (@ISA, @EXPORT_OK);
@ISA       = qw(Exporter);
@EXPORT_OK = qw(Install);

my $insttype;
my @client_contribs = ('oid2name', 'pgbench', 'vacuumlo');
my @client_program_files = (
	'clusterdb',      'createdb',   'createuser',    'dropdb',
	'dropuser',       'ecpg',       'libecpg',       'libecpg_compat',
	'libpgtypes',     'libpq',      'pg_basebackup', 'pg_config',
	'pg_dump',        'pg_dumpall', 'pg_isready',    'pg_receivewal',
	'pg_recvlogical', 'pg_restore', 'psql',          'reindexdb',
	'vacuumdb',       @client_contribs);

sub lcopy
{
	my $src    = shift;
	my $target = shift;

	if (-f $target)
	{
		unlink $target || confess "Could not delete $target\n";
	}

	copy($src, $target)
	  || confess "Could not copy $src to $target\n";

	return;
}

sub Install
{
	$| = 1;

	my $target = shift;
	$insttype = shift;
	$insttype = "all" unless ($insttype);

	# if called from vcregress, the config will be passed to us
	# so no need to re-include these
	our $config = shift;
	unless ($config)
	{

		# suppress warning about harmless redeclaration of $config
		no warnings 'misc';
		do "config_default.pl";
		do "config.pl" if (-f "config.pl");
	}

	chdir("../../..")    if (-f "../../../configure");
	chdir("../../../..") if (-f "../../../../configure");
	my $conf = "";
	if (-d "debug")
	{
		$conf = "debug";
	}
	if (-d "release")
	{
		$conf = "release";
	}
	die "Could not find debug or release binaries" if ($conf eq "");
	my $majorver = DetermineMajorVersion();
	print "Installing version $majorver for $conf in $target\n";

	my @client_dirs = ('bin', 'lib', 'share', 'symbols');
	my @all_dirs = (
		@client_dirs, 'doc', 'doc/contrib', 'doc/extension', 'share/contrib',
		'share/extension', 'share/timezonesets', 'share/tsearch_data');
	if ($insttype eq "client")
	{
		EnsureDirectories($target, @client_dirs);
	}
	else
	{
		EnsureDirectories($target, @all_dirs);
	}

	CopySolutionOutput($conf, $target);
	my $sample_files = [];
	my @top_dir      = ("src");
	@top_dir = ("src\\bin", "src\\interfaces") if ($insttype eq "client");
	File::Find::find(
		{
			wanted => sub {
				/^.*\.sample\z/s
				  && push(@$sample_files, $File::Find::name);

				# Don't find files of in-tree temporary installations.
				$_ eq 'share' and $File::Find::prune = 1;
			}
		},
		@top_dir);
	CopySetOfFiles('config files', $sample_files, $target . '/share/');
	CopyFiles(
		'Import libraries',
		$target . '/lib/',
		"$conf\\", "postgres\\postgres.lib", "libpgcommon\\libpgcommon.lib",
		"libpgport\\libpgport.lib");
	CopyContribFiles($config, $target);
	CopyIncludeFiles($target);

	if ($insttype ne "client")
	{
		CopySetOfFiles(
			'timezone names',
			[ glob('src\timezone\tznames\*.txt') ],
			$target . '/share/timezonesets/');
		CopyFiles(
			'timezone sets',
			$target . '/share/timezonesets/',
			'src/timezone/tznames/', 'Default', 'Australia', 'India');
		CopySetOfFiles(
			'BKI files',
			[ glob("src\\backend\\catalog\\postgres.*") ],
			$target . '/share/');
		CopySetOfFiles(
			'SQL files',
			[ glob("src\\backend\\catalog\\*.sql") ],
			$target . '/share/');
		CopyFiles(
			'Information schema data', $target . '/share/',
			'src/backend/catalog/',    'sql_features.txt');
		CopyFiles(
			'Error code data',    $target . '/share/',
			'src/backend/utils/', 'errcodes.txt');
		GenerateConversionScript($target);
		GenerateTimezoneFiles($target, $conf);
		GenerateTsearchFiles($target);
		CopySetOfFiles(
			'Stopword files',
			[ glob("src\\backend\\snowball\\stopwords\\*.stop") ],
			$target . '/share/tsearch_data/');
		CopySetOfFiles(
			'Dictionaries sample files',
			[ glob("src\\backend\\tsearch\\dicts\\*_sample*") ],
			$target . '/share/tsearch_data/');

		my $pl_extension_files = [];
		my @pldirs             = ('src/pl/plpgsql/src');
		push @pldirs, "src/pl/plperl"   if $config->{perl};
		push @pldirs, "src/pl/plpython" if $config->{python};
		push @pldirs, "src/pl/tcl"      if $config->{tcl};
		File::Find::find(
			{
				wanted => sub {
					/^(.*--.*\.sql|.*\.control)\z/s
					  && push(@$pl_extension_files, $File::Find::name);

					# Don't find files of in-tree temporary installations.
					$_ eq 'share' and $File::Find::prune = 1;
				}
			},
			@pldirs);
		CopySetOfFiles('PL Extension files',
			$pl_extension_files, $target . '/share/extension/');
	}

	GenerateNLSFiles($target, $config->{nls}, $majorver) if ($config->{nls});

	print "Installation complete.\n";
	return;
}

sub EnsureDirectories
{
	my $target = shift;
	mkdir $target unless -d ($target);
	while (my $d = shift)
	{
		mkdir $target . '/' . $d unless -d ($target . '/' . $d);
	}
	return;
}

sub CopyFiles
{
	my $what    = shift;
	my $target  = shift;
	my $basedir = shift;

	print "Copying $what";
	while (my $f = shift)
	{
		print ".";
		$f = $basedir . $f;
		die "No file $f\n" if (!-f $f);
		lcopy($f, $target . basename($f));
	}
	print "\n";
	return;
}

sub CopySetOfFiles
{
	my $what   = shift;
	my $flist  = shift;
	my $target = shift;
	print "Copying $what" if $what;
	foreach (@$flist)
	{
		my $tgt = $target . basename($_);
		print ".";
		lcopy($_, $tgt) || croak "Could not copy $_: $!\n";
	}
	print "\n";
	return;
}

sub CopySolutionOutput
{
	my $conf   = shift;<commit_msg>Return a value from Install.pm's lcopy function<commit_after>package Install;

#
# Package that provides 'make install' functionality for msvc builds
#
# src/tools/msvc/Install.pm
#
use strict;
use warnings;
use Carp;
use File::Basename;
use File::Copy;
use File::Find ();

use Exporter;
our (@ISA, @EXPORT_OK);
@ISA       = qw(Exporter);
@EXPORT_OK = qw(Install);

my $insttype;
my @client_contribs = ('oid2name', 'pgbench', 'vacuumlo');
my @client_program_files = (
	'clusterdb',      'createdb',   'createuser',    'dropdb',
	'dropuser',       'ecpg',       'libecpg',       'libecpg_compat',
	'libpgtypes',     'libpq',      'pg_basebackup', 'pg_config',
	'pg_dump',        'pg_dumpall', 'pg_isready',    'pg_receivewal',
	'pg_recvlogical', 'pg_restore', 'psql',          'reindexdb',
	'vacuumdb',       @client_contribs);

sub lcopy
{
	my $src    = shift;
	my $target = shift;

	if (-f $target)
	{
		unlink $target || confess "Could not delete $target\n";
	}

	(my $retval = copy($src, $target))
	  || confess "Could not copy $src to $target\n";

	return $retval;
}

sub Install
{
	$| = 1;

	my $target = shift;
	$insttype = shift;
	$insttype = "all" unless ($insttype);

	# if called from vcregress, the config will be passed to us
	# so no need to re-include these
	our $config = shift;
	unless ($config)
	{

		# suppress warning about harmless redeclaration of $config
		no warnings 'misc';
		do "config_default.pl";
		do "config.pl" if (-f "config.pl");
	}

	chdir("../../..")    if (-f "../../../configure");
	chdir("../../../..") if (-f "../../../../configure");
	my $conf = "";
	if (-d "debug")
	{
		$conf = "debug";
	}
	if (-d "release")
	{
		$conf = "release";
	}
	die "Could not find debug or release binaries" if ($conf eq "");
	my $majorver = DetermineMajorVersion();
	print "Installing version $majorver for $conf in $target\n";

	my @client_dirs = ('bin', 'lib', 'share', 'symbols');
	my @all_dirs = (
		@client_dirs, 'doc', 'doc/contrib', 'doc/extension', 'share/contrib',
		'share/extension', 'share/timezonesets', 'share/tsearch_data');
	if ($insttype eq "client")
	{
		EnsureDirectories($target, @client_dirs);
	}
	else
	{
		EnsureDirectories($target, @all_dirs);
	}

	CopySolutionOutput($conf, $target);
	my $sample_files = [];
	my @top_dir      = ("src");
	@top_dir = ("src\\bin", "src\\interfaces") if ($insttype eq "client");
	File::Find::find(
		{
			wanted => sub {
				/^.*\.sample\z/s
				  && push(@$sample_files, $File::Find::name);

				# Don't find files of in-tree temporary installations.
				$_ eq 'share' and $File::Find::prune = 1;
			}
		},
		@top_dir);
	CopySetOfFiles('config files', $sample_files, $target . '/share/');
	CopyFiles(
		'Import libraries',
		$target . '/lib/',
		"$conf\\", "postgres\\postgres.lib", "libpgcommon\\libpgcommon.lib",
		"libpgport\\libpgport.lib");
	CopyContribFiles($config, $target);
	CopyIncludeFiles($target);

	if ($insttype ne "client")
	{
		CopySetOfFiles(
			'timezone names',
			[ glob('src\timezone\tznames\*.txt') ],
			$target . '/share/timezonesets/');
		CopyFiles(
			'timezone sets',
			$target . '/share/timezonesets/',
			'src/timezone/tznames/', 'Default', 'Australia', 'India');
		CopySetOfFiles(
			'BKI files',
			[ glob("src\\backend\\catalog\\postgres.*") ],
			$target . '/share/');
		CopySetOfFiles(
			'SQL files',
			[ glob("src\\backend\\catalog\\*.sql") ],
			$target . '/share/');
		CopyFiles(
			'Information schema data', $target . '/share/',
			'src/backend/catalog/',    'sql_features.txt');
		CopyFiles(
			'Error code data',    $target . '/share/',
			'src/backend/utils/', 'errcodes.txt');
		GenerateConversionScript($target);
		GenerateTimezoneFiles($target, $conf);
		GenerateTsearchFiles($target);
		CopySetOfFiles(
			'Stopword files',
			[ glob("src\\backend\\snowball\\stopwords\\*.stop") ],
			$target . '/share/tsearch_data/');
		CopySetOfFiles(
			'Dictionaries sample files',
			[ glob("src\\backend\\tsearch\\dicts\\*_sample*") ],
			$target . '/share/tsearch_data/');

		my $pl_extension_files = [];
		my @pldirs             = ('src/pl/plpgsql/src');
		push @pldirs, "src/pl/plperl"   if $config->{perl};
		push @pldirs, "src/pl/plpython" if $config->{python};
		push @pldirs, "src/pl/tcl"      if $config->{tcl};
		File::Find::find(
			{
				wanted => sub {
					/^(.*--.*\.sql|.*\.control)\z/s
					  && push(@$pl_extension_files, $File::Find::name);

					# Don't find files of in-tree temporary installations.
					$_ eq 'share' and $File::Find::prune = 1;
				}
			},
			@pldirs);
		CopySetOfFiles('PL Extension files',
			$pl_extension_files, $target . '/share/extension/');
	}

	GenerateNLSFiles($target, $config->{nls}, $majorver) if ($config->{nls});

	print "Installation complete.\n";
	return;
}

sub EnsureDirectories
{
	my $target = shift;
	mkdir $target unless -d ($target);
	while (my $d = shift)
	{
		mkdir $target . '/' . $d unless -d ($target . '/' . $d);
	}
	return;
}

sub CopyFiles
{
	my $what    = shift;
	my $target  = shift;
	my $basedir = shift;

	print "Copying $what";
	while (my $f = shift)
	{
		print ".";
		$f = $basedir . $f;
		die "No file $f\n" if (!-f $f);
		lcopy($f, $target . basename($f)) || croak "Could not copy $f: $!\n";
	}
	print "\n";
	return;
}

sub CopySetOfFiles
{
	my $what   = shift;
	my $flist  = shift;
	my $target = shift;
	print "Copying $what" if $what;
	foreach (@$flist)
	{
		my $tgt = $target . basename($_);
		print ".";
		lcopy($_, $tgt) || croak "Could not copy $_: $!\n";
	}
	print "\n";
	return;
}

sub CopySolutionOutput
{
	my $conf   = shift;
{'fraction_non_alphanumeric': 0.1979565772669221, 'fraction_numerical': 0.0007297938332421091, 'mean_word_length': 3.285770132916341, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2456083', 'n_tokens_mistral': 4443, 'n_tokens_neox': 4070, 'n_words': 960}