<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">#!/usr/bin/perl
use strict;
my %package;
my %category;

sub parse_target_metadata() {
	my ($target, @target, $profile);	
	while (&lt;&gt;) {
		chomp;
		/^Target:\s*((.+)-(\d+\.\d+))\s*$/ and do {
			my $conf = uc $3.'_'.$2;
			$conf =~ tr/\.-/__/;
			$target = {
				id =&gt; $1,
				conf =&gt; $conf,
				board =&gt; $2,
				kernel =&gt; $3,
				profiles =&gt; []
			};
			push @target, $target;
		};
		/^Target-Name:\s*(.+)\s*$/ and $target-&gt;{name} = $1;
		/^Target-Path:\s*(.+)\s*$/ and $target-&gt;{path} = $1;
		/^Target-Arch:\s*(.+)\s*$/ and $target-&gt;{arch} = $1;
		/^Target-Features:\s*(.+)\s*$/ and $target-&gt;{features} = [ split(/\s+/, $1) ];
		/^Target-Description:/ and do {
			my $desc;
			while (&lt;&gt;) {
				last if /^@@/;
				$desc .= $_;
			}
			$target-&gt;{desc} = $desc;
		};
		/^Linux-Version:\s*(.+)\s*$/ and $target-&gt;{version} = $1;
		/^Linux-Release:\s*(.+)\s*$/ and $target-&gt;{release} = $1;
		/^Linux-Kernel-Arch:\s*(.+)\s*$/ and $target-&gt;{karch} = $1;
		/^Default-Packages:\s*(.+)\s*$/ and $target-&gt;{packages} = [ split(/\s+/, $1) ];
		/^Target-Profile:\s*(.+)\s*$/ and do {
			$profile = {
				id =&gt; $1,
				name =&gt; $1,
				packages =&gt; []
			};
			push @{$target-&gt;{profiles}}, $profile;
		};
		/^Target-Profile-Name:\s*(.+)\s*$/ and $profile-&gt;{name} = $1;
		/^Target-Profile-Packages:\s*(.*)\s*$/ and $profile-&gt;{packages} = [ split(/\s+/, $1) ];
		/^Target-Profile-Description:/ and do {
			my $desc;
			while (&lt;&gt;) {
				last if /^@@/;
				$desc .= $_;
			}
			$profile-&gt;{desc} = $desc;
		};
		/^Target-Profile-Kconfig:/ and $profile-&gt;{kconfig} = 1;
	}
	foreach my $target (@target) {
		@{$target-&gt;{profiles}} &gt; 0 or $target-&gt;{profiles} = [
			{
				id =&gt; 'Default',
				name =&gt; 'Default',
				packages =&gt; []
			}
		];
	}
	return @target;
}

sub parse_package_metadata() {
	my $pkg;
	my $makefile;
	my $src;
	while (&lt;&gt;) {
		chomp;
		/^Source-Makefile: \s*(.+\/([^\/]+)\/Makefile)\s*$/ and do {
			$makefile = $1;
			$src = $2;
			undef $pkg;
		};
		/^Package: \s*(.+)\s*$/ and do {
			$pkg = {};
			$pkg-&gt;{src} = $src;
			$pkg-&gt;{makefile} = $makefile;
			$pkg-&gt;{name} = $1;
			$pkg-&gt;{default} = "m if ALL";
			$package{$1} = $pkg;
		};
		/^Version: \s*(.+)\s*$/ and $pkg-&gt;{version} = $1;
		/^Title: \s*(.+)\s*$/ and $pkg-&gt;{title} = $1;
		/^Menu: \s*(.+)\s*$/ and $pkg-&gt;{menu} = $1;
		/^Submenu: \s*(.+)\s*$/ and $pkg-&gt;{submenu} = $1;
		/^Submenu-Depends: \s*(.+)\s*$/ and $pkg-&gt;{submenudep} = $1;
		/^Default: \s*(.+)\s*$/ and $pkg-&gt;{default} = $1;
		/^Provides: \s*(.+)\s*$/ and do {
			my @vpkg = split /\s+/, $1;
			foreach my $vpkg (@vpkg) {
				$package{$vpkg} or $package{$vpkg} = { vdepends =&gt; [] };
				push @{$package{$vpkg}-&gt;{vdepends}}, $pkg-&gt;{name};
			}
		};
		/^Depends: \s*(.+)\s*$/ and do {
			my @dep = split /\s+/, $1;
			$pkg-&gt;{depends} = \@dep;
		};
		/^Category: \s*(.+)\s*$/ and do {
			$pkg-&gt;{category} = $1;
			defined $category{$1} or $category{$1} = {};
			defined $category{$1}-&gt;{$src} or $category{$1}-&gt;{$src} = [];
			push @{$category{$1}-&gt;{$src}}, $pkg;
		};
		/^Description: \s*(.*)\s*$/ and do {
			my $desc = "\t\t$1\n\n";
			my $line;
			while ($line = &lt;&gt;) {
				last if $line =~ /^@@/;
				$desc .= "\t\t$line";
			}
			$pkg-&gt;{description} = $desc;
		};
		/^Config: \s*(.*)\s*$/ and do {
			my $conf = "$1\n";
			my $line;
			while ($line = &lt;&gt;) {
				last if $line =~ /^@@/;
				$conf .= "$line";
			}
			$pkg-&gt;{config} = $conf;
		}
	}
	return %category;
}


sub gen_target_mk() {
	my @target = parse_target_metadata();
	
	@target = sort {
		$a-&gt;{id} cmp $b-&gt;{id}
	} @target;
	
	foreach my $target (@target) {
		my ($profiles_def, $profiles_eval);
		my $conf = uc $target-&gt;{kernel}.'_'.$target-&gt;{board};
		$conf =~ tr/\.-/__/;
		
		foreach my $profile (@{$target-&gt;{profiles}}) {
			$profiles_def .= "
  define Profile/$conf\_$profile-&gt;{id}
    ID:=$profile-&gt;{id}
    NAME:=$profile-&gt;{name}
    PACKAGES:=".join(" ", @{$profile-&gt;{packages}})."\n";
			$profile-&gt;{kconfig} and $profiles_def .= "    KCONFIG:=1\n";
			$profiles_def .= "  endef";
			$profiles_eval .= "
\$(eval \$(call AddProfile,$conf\_$profile-&gt;{id}))"
		}
		print "
ifeq (\$(CONFIG_LINUX_$conf),y)
  define Target
    KERNEL:=$target-&gt;{kernel}
    BOARD:=$target-&gt;{board}
    BOARDNAME:=$target-&gt;{name}
    LINUX_VERSION:=$target-&gt;{version}
    LINUX_RELEASE:=$target-&gt;{release}
    LINUX_KARCH:=$target-&gt;{karch}
    DEFAULT_PACKAGES:=".join(" ", @{$target-&gt;{packages}})."
  endef$profiles_def
endif$profiles_eval

"
	}
	print "\$(eval \$(call Target))\n";
}

sub target_config_features(@) {
	my $ret;

	while ($_ = shift @_) {
		/broken/ and $ret .= "\tdepends BROKEN\n";
		/pci/ and $ret .= "\tselect PCI_SUPPORT\n";
		/usb/ and $ret .= "\tselect USB_SUPPORT\n";
		/atm/ and $ret .= "\tselect ATM_SUPPORT\n";
		/pcmcia/ and $ret .= "\tselect PCMCIA_SUPPORT\n";
		/video/ and $ret .= "\tselect VIDEO_SUPPORT\n";
		/squashfs/ and $ret .= "\tselect USES_SQUASHFS\n";
		/jffs2/ and $ret .= "\tselect USES_JFFS2\n";
		/ext2/ and $ret .= "\tselect USES_EXT2\n";
	}
	return $ret;
}


sub gen_target_config() {
	my @target = parse_target_metadata();

	@target = sort {
		$a-&gt;{name} cmp $b-&gt;{name}
	} @target;
	
	
	print &lt;&lt;EOF;
choice
	prompt "Target System"
	default LINUX_2_4_BRCM
	
EOF

	foreach my $target (@target) {
		my $features = target_config_features(@{$target-&gt;{features}});
		my $help = $target-&gt;{desc};
		my $kernel = $target-&gt;{kernel};
		$kernel =~ tr/./_/;

		chomp $features;
		$features .= "\n";
		if ($help =~ /\w+/) {
			$help =~ s/^\s*/\t  /mg;
			$help = "\thelp\n$help";
		} else {
			undef $help;
		}
	
		print &lt;&lt;EOF
config LINUX_$target-&gt;{conf}
	bool "$target-&gt;{name}"
	select $target-&gt;{arch}
	select LINUX_$kernel
$features$help

EOF
	}

	print &lt;&lt;EOF;
if DEVEL

config LINUX_2_6_ARM
	bool "UNSUPPORTED little-endian arm platform"
	depends BROKEN
	select LINUX_2_6
	select arm

config LINUX_2_6_CRIS
	bool "UNSUPPORTED cris platform"
	depends BROKEN
	select LINUX_2_6
	select cris

config LINUX_2_6_M68K
	bool "UNSUPPORTED m68k platform"
	depends BROKEN
	select LINUX_2_6
	select m68k

config LINUX_2_6_SH3
	bool "UNSUPPORTED little-endian sh3 platform"
	depends BROKEN
	select LINUX_2_6
	select sh3

config LINUX_2_6_SH3EB
	bool "UNSUPPORTED big-endian sh3 platform"
	depends BROKEN
	select LINUX_2_6
	select sh3eb

config LINUX_2_6_SH4
	bool "UNSUPPORTED little-endian sh4 platform"
	depends BROKEN
	select LINUX_2_6
	select sh4

config LINUX_2_6_SH4EB
	bool "UNSUPPORTED big-endian sh4 platform"
	depends BROKEN
	select LINUX_2_6
	select sh4eb

config LINUX_2_6_SPARC
	bool "UNSUPPORTED sparc platform"
	depends BROKEN
	select LINUX_2_6
	select sparc

endif

endchoice

choice
	prompt "Target Profile"

EOF
	
	foreach my $target (@target) {
		my $profiles = $target-&gt;{profiles};
		
		foreach my $profile (@$profiles) {
			print &lt;&lt;EOF;
config LINUX_$target-&gt;{conf}_$profile-&gt;{id}
	bool "$profile-&gt;{name}"
	depends LINUX_$target-&gt;{conf}
EOF
			$profile-&gt;{kconfig} and print "\tselect PROFILE_KCONFIG\n";
			my %pkgs;
			foreach my $pkg (@{$target-&gt;{packages}}, @{$profile-&gt;{packages}}) {
				$pkgs{$pkg} = 1;
			}
			foreach my $pkg (keys %pkgs) {
				print "\tselect DEFAULT_$pkg\n" unless ($pkg =~ /^-/ or $pkgs{"-$pkg"});
			}
			print "\n";
		}
	}

	print "endchoice\n";
}

sub find_package_dep($$) {
	my $pkg = shift;
	my $name = shift;
	my $deps = ($pkg-&gt;{vdepends} or $pkg-&gt;{depends});

	return 0 unless defined $deps;
	foreach my $dep (@{$deps}) {
		return 1 if $dep eq $name;
		return 1 if ($package{$dep} and (find_package_dep($package{$dep},$name) == 1));
	}
	return 0;
}

sub package_depends($$) {
	my $a = shift;
	my $b = shift;
	my $ret;

	return 0 if ($a-&gt;{submenu} ne $b-&gt;{submenu});
	if (find_package_dep($a, $b-&gt;{name}) == 1) {
		$ret = 1;
	} elsif (find_package_dep($b, $a-&gt;{name}) == 1) {
		$ret = -1;
	} else {
		return 0;
	}
	return $ret;
}

sub mconf_depends($$) {
	my $depends = shift;
	my $only_dep = shift;
	my $res;

	$depends or return;
	my @depends = @$depends;
	foreach my $depend (@depends) {
		my $m = "depends";
		$depend =~ s/^([@\+]+)//;
		my $flags = $1;
		my $vdep;
	
		if ($vdep = $package{$depend}-&gt;{vdepends}) {
			$depend = join("||", map { "PACKAGE_".$_ } @$vdep);
		} else {
			$flags =~ /\+/ and do {
				next if $only_dep;
				$m = "select";

				# Menuconfig will not treat 'select FOO' as a real dependency
				# thus if FOO depends on other config options, these dependencies
				# will not be checked. To fix this, we simply emit all of FOO's
				# depends here as well.
				$package{$depend} and $res .= mconf_depends($package{$depend}-&gt;{depends}, 1);
			};
			$flags =~ /@/ or $depend = "PACKAGE_$depend";
		}
		$res .= "\t\t$m $depend\n";
	}
	return $res;
}

sub print_package_config_category($) {
	my $cat = shift;
	my %menus;
	my %menu_dep;
	
	return unless $category{$cat};
	
	print "menu \"$cat\"\n\n";
	my %spkg = %{$category{$cat}};
	
	foreach my $spkg (sort {uc($a) cmp uc($b)} keys %spkg) {
		foreach my $pkg (@{$spkg{$spkg}}) {
			my $menu = $pkg-&gt;{submenu};
			if ($menu) {
				$menu_dep{$menu} or $menu_dep{$menu} = $pkg-&gt;{submenudep};
			} else {
				$menu = 'undef';
			}
			$menus{$menu} or $menus{$menu} = [];
			push @{$menus{$menu}}, $pkg;
			print "\tconfig DEFAULT_".$pkg-&gt;{name}."\n";
			print "\t\tbool\n\n";
		}
	}
	my @menus = sort {
		($a eq 'undef' ?  1 : 0) or
		($b eq 'undef' ? -1 : 0) or
		($a cmp $b)
	} keys %menus;

	foreach my $menu (@menus) {
		my @pkgs = sort {
			package_depends($a, $b) or
			($a-&gt;{name} cmp $b-&gt;{name})
		} @{$menus{$menu}};
		if ($menu ne 'undef') {
			$menu_dep{$menu} and print "if $menu_dep{$menu}\n";
			print "menu \"$menu\"\n";
		}
		foreach my $pkg (@pkgs) {
			my $title = $pkg-&gt;{name};
			my $c = (72 - length($pkg-&gt;{name}) - length($pkg-&gt;{title}));
			if ($c &gt; 0) {
				$title .= ("." x $c). " ". $pkg-&gt;{title};
			}
			print "\t";
			$pkg-&gt;{menu} and print "menu";
			print "config PACKAGE_".$pkg-&gt;{name}."\n";
			print "\t\ttristate \"$title\"\n";
			print "\t\tdefault y if DEFAULT_".$pkg-&gt;{name}."\n";
			foreach my $default (split /\s*,\s*/, $pkg-&gt;{default}) {
				print "\t\tdefault $default\n";
			}
			print mconf_depends($pkg-&gt;{depends}, 0);
			print "\t\thelp\n";
			print $pkg-&gt;{description};
			print "\n";

			$pkg-&gt;{config} and print $pkg-&gt;{config}."\n";
		}
		if ($menu ne 'undef') {
			print "endmenu\n";
			$menu_dep{$menu} and print "endif\n";
		}
	}
	print "endmenu\n\n";
	
	undef $category{$cat};
}

sub gen_package_config() {
	parse_package_metadata();
	print_package_config_category 'Base system';
	foreach my $cat (keys %category) {
		print_package_config_category $cat;
	}
}

sub parse_command() {
	my $cmd = shift @ARGV;
	for ($cmd) {
		/^target_mk$/ and return gen_target_mk();
		/^target_config$/ and return gen_target_config();
		/^package_config$/ and return gen_package_config();
	}
	print &lt;&lt;EOF
Available Commands:
	$0 target_mk [file] 		Target metadata in makefile format
	$0 target_config [file] 	Target metadata in Kconfig format
	$0 package_config [file] 	Package metadata in Kconfig format
EOF
}

parse_command();
</pre></body></html>