summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarald van Dijk <truedfx@gentoo.org>2009-10-27 20:52:54 +0059
committerHarald van Dijk <truedfx@gentoo.org>2009-10-27 20:52:54 +0059
commitc71a3ae87a26bffd414bdaf36b05f3dfba5ea8f5 (patch)
treeadfac14d4635e418b48078c10b1aac314138b119 /ufed.pl.in
parentufed-0.40-useorder.patch (diff)
downloadufed-c71a3ae87a26bffd414bdaf36b05f3dfba5ea8f5.tar.gz
ufed-c71a3ae87a26bffd414bdaf36b05f3dfba5ea8f5.tar.bz2
ufed-c71a3ae87a26bffd414bdaf36b05f3dfba5ea8f5.zip
autotoolize; don't show profile flags as enabled with -*
Diffstat (limited to 'ufed.pl.in')
-rw-r--r--ufed.pl.in304
1 files changed, 304 insertions, 0 deletions
diff --git a/ufed.pl.in b/ufed.pl.in
new file mode 100644
index 0000000..a6f62d4
--- /dev/null
+++ b/ufed.pl.in
@@ -0,0 +1,304 @@
+#!@PERL@ -I@perldir@
+use strict;
+use warnings;
+
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/ufed/ufed.pl,v 1.45 2005/10/18 11:14:33 truedfx Exp $
+
+use Portage;
+
+my $version = '@PACKAGE_VERSION@';
+
+my %use_descriptions;
+
+sub finalise(@);
+sub flags_dialog();
+sub read_use_descs();
+sub save_flags(@);
+
+delete $Portage::all_flags{'*'};
+
+read_use_descs;
+
+delete @use_descriptions{qw(bootstrap build)};
+
+$Portage::make_conf_flags{'-*'} = 1 if defined $Portage::make_conf_flags{'*'} && !$Portage::make_conf_flags{'*'};
+
+for(keys %Portage::all_flags) {
+ @{$use_descriptions{$_}} = "(Unknown)"
+ if not exists $use_descriptions{$_};
+}
+@{$use_descriptions{'-*'}} = 'Never enable any flags other than those specified in /etc/make.conf';
+
+for(@Portage::archs) {
+ delete $Portage::default_flags{$_};
+ delete $Portage::all_flags{$_};
+ delete $use_descriptions{$_};
+}
+for(keys %Portage::use_masked_flags) {
+ my $masked = 1;
+ for(values %{$Portage::use_masked_flags{$_}}) {
+ last if not($masked &&= $_);
+ }
+ if($masked) {
+ delete $Portage::default_flags{$_};
+ delete $Portage::all_flags{$_};
+ delete $use_descriptions{$_};
+ }
+}
+
+flags_dialog;
+
+sub finalise(@) {
+ return sort {
+ ($a ne '-*') <=> ($b ne '-*')
+ ||
+ ($a =~ /^-/) <=> ($b =~ /^-/)
+ ||
+ $a cmp $b
+ } @_;
+}
+
+sub flags_dialog() {
+ use POSIX ();
+ POSIX::dup2 1, 3;
+ POSIX::dup2 1, 4;
+ my ($iread, $iwrite) = POSIX::pipe;
+ my ($oread, $owrite) = POSIX::pipe;
+ my $child = fork;
+ die "fork() failed\n" if not defined $child;
+ if($child == 0) {
+ POSIX::close $iwrite;
+ POSIX::close $oread;
+ POSIX::dup2 $iread, 3;
+ POSIX::close $iread;
+ POSIX::dup2 $owrite, 4;
+ POSIX::close $owrite;
+ my $interface = 'ufed-curses';
+ exec { "@libexecdir@/$interface" } $interface or
+ do { print STDERR "Couldn't launch $interface\n"; exit 3 }
+ }
+ POSIX::close $iread;
+ POSIX::close $owrite;
+ if(open my $fh, '>&=', $iwrite) {
+ my @flags = sort { uc $a cmp uc $b } keys %use_descriptions;
+ my %descriptions;
+ for(my $flag=0; $flag<@flags; $flag++) {
+ my $flag = $flags[$flag];
+ print $fh $flag;
+ print $fh defined $Portage::make_conf_flags{$flag} ? $Portage::make_conf_flags{$flag} ? ' on ' : ' off ' : ' def ';
+ print $fh exists $Portage::make_defaults_flags{$flag} ? $Portage::make_defaults_flags{$flag} ? '(+' :'(-' :'( ' ;
+ print $fh exists $Portage::use_defaults_flags{$flag} ? $Portage::use_defaults_flags{$flag} ? '+' : '-' : ' ' ;
+ print $fh exists $Portage::make_conf_flags{$flag} ? $Portage::make_conf_flags{$flag} ? '+)': '-)': ' )';
+ print $fh ' ', scalar(@{$use_descriptions{$flag}}), "\n";
+ print $fh $_, "\n" for(@{$use_descriptions{$flag}});
+ }
+ close $fh;
+ } else {
+ die "Couldn't let interface know of flags\n";
+ }
+ POSIX::close $iwrite;
+ wait;
+ open my $fh, '<&=', $oread or die "Couldn't read output.\n";
+ if(POSIX::WIFEXITED($?)) {
+ my $rc = POSIX::WEXITSTATUS($?);
+ if($rc==0) {
+ my @flags = grep { $_ ne '--*' } do { local $/; split /\n/, <$fh> };
+ save_flags finalise @flags;
+ } elsif($rc==1)
+ { print "Cancelled, not saving changes.\n" }
+ exit $rc;
+ } elsif(POSIX::WIFSIGNALED($?))
+ { kill POSIX::WTERMSIG($?), $$ }
+ else
+ { exit 127 }
+}
+
+sub read_use_descs() {
+ my %_use_descriptions;
+ for my $dir(@Portage::portagedirs) {
+ for(Portage::noncomments "$dir/profiles/use.desc") {
+ my ($flag, $desc) = /^(.*?)\s+-\s+(.*)$/ or next;
+ $_use_descriptions{$flag}{$desc} = 1;
+ }
+ }
+ my %_use_local_descriptions;
+ for my $dir(@Portage::portagedirs) {
+ for(Portage::noncomments "$dir/profiles/use.local.desc") {
+ my ($pkg, $flag, $desc) = /^(.*?):(.*?)\s+-\s+(.*)$/ or next;
+ $_use_local_descriptions{$flag}{$desc}{$pkg} = 1;
+ }
+ }
+ local $"=", ";
+ for(sort keys %_use_descriptions)
+ { @{$use_descriptions{$_}} = sort keys %{$_use_descriptions{$_}} }
+ for(sort keys %_use_local_descriptions) {
+ for my $desc(sort keys %{$_use_local_descriptions{$_}})
+ { push @{$use_descriptions{$_}}, "Local flag: $desc (@{[sort keys %{$_use_local_descriptions{$_}{$desc}}]})" }
+ }
+}
+
+sub save_flags(@) {
+ my $BLANK = qr{(?:[ \n\t]+|#.*)+}; # whitespace and comments
+ my $UBLNK = qr{(?: # as above, but scan for #USE=
+ [ \n\t]+ |
+ \#[ \t]*USE[ \t]*=.*(\n?) | # place capture after USE=... line
+ \#.*)+}x;
+ my $IDENT = qr{([^ \\\n\t'"{}=#]+)}; # identifiers
+ my $ASSIG = qr{=}; # assignment operator
+ my $UQVAL = qr{(?:[^ \\\n\t'"#]+|\\.)+}s; # unquoted value
+ my $SQVAL = qr{'[^']*'}; # singlequoted value
+ my $DQVAL = qr{"(?:[^\\"]|\\.)*"}s; # doublequoted value
+ my $BNUQV = qr{(?:[^ \\\n\t'"#]+|\\\n()|\\.)+}s;# unquoted value (scan for \\\n)
+ my $BNDQV = qr{"(?:[^\\"]|\\\n()|\\.)*"}s; # doublequoted value (scan for \\\n)
+
+ my (@flags) = @_;
+ my $contents;
+
+ {
+ open my $makeconf, '<', '/etc/make.conf' or die "Couldn't open /etc/make.conf\n";
+ open my $makeconfold, '>', '/etc/make.conf.old' or die "Couldn't open /etc/make.conf.old\n";
+ local $/;
+ $_ = <$makeconf>;
+ print $makeconfold $_;
+ close $makeconfold;
+ close $makeconf;
+ }
+
+ my $sourcing = 0;
+ eval {
+ # USE comment start/end (start/end of newline character at the end, specifically)
+ # default to end of make.conf, to handle make.confs without #USE=
+ my($ucs, $uce) = (length, length);
+ my $flags = '';
+ pos = 0;
+ for(;;) {
+ if(/\G$UBLNK/gc) {
+ ($ucs, $uce) = ($-[1], $+[1]) if defined $1;
+ }
+ last if pos == length;
+ my $flagatstartofline = do {
+ my $linestart = 1+rindex $_, "\n", pos()-1;
+ my $line = substr($_, $linestart, pos()-$linestart);
+ $line !~ /[^ \t]/;
+ };
+ /\G$IDENT/gc or die;
+ my $name = $1;
+ /\G$BLANK/gc;
+ if($name ne 'source') {
+ /\G$ASSIG/gc or die;
+ /\G$BLANK/gc;
+ } else {
+ $sourcing = 1;
+ }
+ die if pos == length;
+ if($name ne 'USE') {
+ /\G(?:$UQVAL|$SQVAL|$DQVAL)+/gc or die;
+ } else {
+ my $start = pos;
+ /\G(?:$BNUQV|$SQVAL|$BNDQV)+/gc or die;
+ my $end = pos;
+ # save whether user uses backslash-newline
+ my $bsnl = defined $1 || defined $2;
+ # start of the line is one past the last newline; also handles first line
+ my $linestart = 1+rindex $_, "\n", $start-1;
+ # everything on the current line before the USE flags, plus one for the "
+ my $line = substr($_, $linestart, $start-$linestart).' ';
+ # only indent if USE starts a line
+ my $blank = $flagatstartofline ? $line : "";
+ $blank =~ s/[^ \t]/ /g;
+ # word wrap
+ if(@flags != 0) {
+ my $length = 0;
+ while($line =~ /(.)/g) {
+ if($1 ne "\t") {
+ $length++;
+ } else {
+ # no best tab size discussions, please. terminals use ts=8.
+ $length&=~8;
+ $length+=8;
+ }
+ }
+ my $blanklength = $blank ne '' ? $length : 0;
+ # new line, using backslash-newline if the user did that
+ my $nl = ($bsnl ? " \\\n" : "\n").$blank;
+ my $linelength = $bsnl ? 76 : 78;
+ my $flag = $flags[0];
+ if($blanklength != 0 || length $flag <= $linelength) {
+ $flags = $flag;
+ $length += length $flag;
+ } else {
+ $flags = $nl.$flag;
+ $length = length $flag;
+ }
+ for $flag(@flags[1..$#flags]) {
+ if($length + 1 + length $flag <= $linelength) {
+ $flags .= " $flag";
+ $length += 1+length $flag;
+ } else {
+ $flags .= $nl.$flag;
+ $length = $blanklength + length $flag;
+ }
+ }
+ }
+ # replace the current USE flags with the modified ones
+ substr($_, $start, $end-$start) = "\"$flags\"";
+ # and have the next search start after our new flags
+ pos = $start + 2 + length $flags;
+ # and end this
+ undef $flags;
+ last;
+ }
+ }
+ if(defined $flags) { # if we didn't replace the flags, tack them after the last #USE= or at the end
+ $flags = '';
+ if(@flags != 0) {
+ $flags = $flags[0];
+ my $length = 5 + length $flags[0];
+ for my $flag(@flags[1..$#flags]) {
+ if($length + 1 + length $flag <= 78) {
+ $flags .= " $flag";
+ $length += 1+length $flag;
+ } else {
+ $flags .= "\n $flag";
+ $length = 5+length $flag;
+ }
+ }
+ }
+ substr($_, $ucs, $uce-$ucs) = "\nUSE=\"$flags\"\n";
+ } else { # if we replaced the flags, delete any further overrides
+ for(;;) {
+ my $start = pos;
+ /\G$BLANK/gc;
+ last if pos == length;
+ /\G$IDENT/gc or die;
+ my $name = $1;
+ /\G$BLANK/gc;
+ if($name ne 'source') {
+ /\G$ASSIG/gc or die;
+ /\G$BLANK/gc;
+ } else {
+ $sourcing = 1;
+ }
+ /\G(?:$UQVAL|$SQVAL|$DQVAL)+/gc or die;
+ my $end = pos;
+ if($name eq 'USE') {
+ substr($_, $start, $end-$start) = '';
+ pos = $start;
+ }
+ }
+ }
+ };
+ die "Parse error when writing make.conf - did you modify it while ufed was running?\n" if $@;
+
+ print STDERR <<EOF if $sourcing;
+Warning: source command found in /etc/make.conf. Flags may
+be saved incorrectly if the sourced file modifies them.
+EOF
+ {
+ open my $makeconf, '>', '/etc/make.conf' or die "Couldn't open /etc/make.conf\n";
+ print $makeconf $_;
+ close $makeconf;
+ }
+}