update-headers   [plain text]


#!/usr/bin/perl

if (!$ENV{"INSTALL_DIR"} or !$ENV{"PUBLIC_HEADERS_FOLDER_PATH"} or !$ENV{"PRIVATE_HEADERS_FOLDER_PATH"}) {
	die "Cannot update headers, missing ENV vars\n";
}

$DO_SPLIT = ($#ARGV >= 0 and $ARGV[0] eq "split");

$USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK = $ENV{"USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK"} eq "YES";

$API_BASE = $ENV{"INSTALL_DIR"} . "/" . $ENV{"PUBLIC_HEADERS_FOLDER_PATH"};
$SPI_BASE = $ENV{"INSTALL_DIR"} . "/" . $ENV{"PRIVATE_HEADERS_FOLDER_PATH"};

sub clean_INC {
	my ($inc) = @_;

	$inc =~ s/#ifdef\s+USE_SYSTEMCONFIGURATION_PRIVATE_HEADERS\s*.*?\n#include\s+<SystemConfiguration\/.*?>.*?\n#else.*?\n//;
	$inc =~ s/#endif\s+.*?USE_SYSTEMCONFIGURATION_PRIVATE_HEADERS.*?\n//;

	return $inc;
}

sub clean_API {
	my ($api) = @_;
	my ($api_new);

	$api_new = $DO_SPLIT ? $api : clean_INC($api);
	$api_new =~ s/(__MAC)_\w+\/\*SPI\*\//\1_NA/g;
	$api_new =~ s/#define\t__AVAILABILITY_INTERNAL__.*FUTURE.*\/\*SPI\*\/\n//;
	$api_new =~ s/(__IPHONE)_\w+\/\*SPI\*\//\1_NA/g;

	return $api_new;
}

sub clean_SPI {
	my ($spi) = @_;
	my ($spi_new);

	$spi_new = clean_INC($spi);
	$spi_new =~ s/(__MAC_\w+)\/\*SPI\*\//\1/g;
	$spi_new =~ s/(#define\t__AVAILABILITY_INTERNAL__.*FUTURE.*)\/\*SPI\*\//\1/;
	$spi_new =~ s/(__IPHONE_\w+)\/\*SPI\*\//\1/g;

	return $spi_new;
}

sub create_STUB {
	my ($api_header) = @_;
	my ($stub_new);

	$stub_new = "
#warning \"Please #include <SystemConfiguration/PUBLIC.h> instead of this file directly.\"
#include <SystemConfiguration/PUBLIC.h>
";
	$stub_new =~ s/PUBLIC.h/$api_header/g;

	return $stub_new;
}

#
# Update .../PrivateHeaders
#

opendir(HEADERS, $SPI_BASE);
@headers = readdir(HEADERS);
closedir(HEADERS);

undef $/;
for (@headers) {
	next if ($_ eq '.');
	next if ($_ eq '..');

	$spi_header = $_;
	$spi_path = $SPI_BASE . "/" . $spi_header;
	next if (! -f $spi_path);

	open(SPI, "<", $spi_path);
	$spi = <SPI>;
	close(SPI);

	$spi_new = clean_SPI($spi);
	if ($spi ne $spi_new) {
		printf "cleaning .../PrivateHeaders/%s\n", $spi_header;
		open(SPI, ">", $spi_path);
		print SPI $spi_new;
		close(SPI);
	}
}
$/ = "\n";

#
# Update .../Headers
#

opendir(HEADERS, $API_BASE);
@headers = readdir(HEADERS);
closedir(HEADERS);

undef $/;
for (@headers) {
	next if ($_ eq '.');
	next if ($_ eq '..');

	$api_header = $_;
	$api_path = $API_BASE . "/" . $api_header;
	next if (! -f $api_path);

	open(API, "<", $api_path);
	$api = <API>;
	close(API);

	$api_new = clean_API($api);
	next if ($api eq $api_new);	# if no tweaks needed

	if (!$USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK) {
		printf "cleaning .../Headers/%s\n", $api_header;
		open(API, ">", $api_path);
		print API $api_new;
		close(API);

		if ($DO_SPLIT) {
			$spi_new = clean_SPI($api);
			if ($api_new ne $spi_new) {
				if ((($spi_header) = ($api =~ /#ifdef\s+USE_SYSTEMCONFIGURATION_PRIVATE_HEADERS\s*.*?\n#include\s+<SystemConfiguration\/(.*?\.h)>\s*.*?\n/))) {
					if ($api_header eq $spi_header) {
						die "API & SPI header not unique: $api_header\n";
					}
				} else {
					die "Header missing #ifdef/#else/#endif: $api_header\n";
#					$spi_header = $api_header;
#					$spi_header =~ s/\.h$/PRIVATE.h/;
				}

				printf "  adding .../PrivateHeaders/%s\n", $spi_header;
				$spi_path = $SPI_BASE . "/" . $spi_header;
				open(SPI, ">", $spi_path);
				print SPI $spi_new;
				close(SPI);
			}
		}
	} else {
		$spi_new = clean_SPI($api);
		if ($api_new ne $spi_new) {
			if ((($stub_header) = ($api =~ /#ifdef\s+USE_SYSTEMCONFIGURATION_PRIVATE_HEADERS\s*.*?\n#include\s+<SystemConfiguration\/(.*?\.h)>\s*.*?\n/))) {
				if ($api_header eq $stub_header) {
					die "API & STUB header not unique: $api_header\n";
				}
			} else {
				die "Header missing #ifdef/#else/#endif: $api_header\n";
			}

			printf "updating .../Headers/%s\n", $api_header;
			open(API, ">", $api_path);
			print API $spi_new;
			close(API);

			printf "  adding .../PrivateHeaders/%s (stub)\n", $stub_header;
			$stub_path = $SPI_BASE . "/" . $stub_header;
			$stub_new = create_STUB($api_header);
			open(STUB, ">", $stub_path);
			print STUB $stub_new;
			close(STUB);
		}
	}
}
$/ = "\n";

exit 0;