SOURCES: fixconfig.pl (NEW) - sparky's replacement of `make oldcon...
sparky
sparky at pld-linux.org
Sun Oct 23 02:05:26 CEST 2005
Author: sparky Date: Sun Oct 23 00:05:26 2005 GMT
Module: SOURCES Tag: HEAD
---- Log message:
- sparky's replacement of `make oldconfig` (: it realy works
---- Files affected:
SOURCES:
fixconfig.pl (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/fixconfig.pl
diff -u /dev/null SOURCES/fixconfig.pl:1.1
--- /dev/null Sun Oct 23 02:05:26 2005
+++ SOURCES/fixconfig.pl Sun Oct 23 02:05:21 2005
@@ -0,0 +1,508 @@
+#!/usr/bin/perl
+#
+# better :P, full color `make oldconfig` replacement
+#
+# by sparky at pld-linux.org
+#
+# may be distributed under GPL
+#
+# TODO:
+# - write some doc
+# - better 'select'
+# - finish TODO
+
+use strict;
+use warnings;
+
+my $arch;
+my $dir = "";
+my $mainconf;
+my @addconf;
+my $ask = 1;
+
+while ( my $opt = $ARGV[0] ) {
+ if ( $opt eq "-a" ) {
+ $arch = $ARGV[1];
+ shift @ARGV;
+ } elsif ( $opt eq "-d" ) {
+ $dir = $ARGV[1]."/";
+ shift @ARGV;
+ } elsif ( $opt eq "-s" ) {
+ $ask = 0;
+ } elsif ( not defined $mainconf ) {
+ $mainconf = $opt;
+ } else {
+ push @addconf, $opt;
+ }
+ shift @ARGV;
+}
+unless ( defined $mainconf ) {
+ print<<EOF;
+Usage:
+fixconfig.pl [-a <arch>] [-d <dir>] [-s] <Main config> [Additional configs]
+
+ -a <arch> - architecture to be fixed, if none specified script will try to
+ guess from Main config file name
+ -d <dir> - directory of extracted kernel source
+ -s - sort only, don't ask for new options
+ <Main config> - main config file
+ [Additional configs] - additional config files (script will not ask for
+ options placed in those files
+
+while in non 'sort only' mode press ^[<ENTER> (<ESC><ENTER>) to skip an option
+
+EOF
+ exit;
+}
+unless ( defined $arch ) {
+ if ( $mainconf =~ /kernel-(.*?)(-smp|).config/ ) {
+ $arch = $1;
+ } else {
+ die "Can't guess arch, specify with -a <arch>\n";
+ }
+}
+
+my $B="\033[1m"; # Bold
+my $r="\033[31m"; # red
+my $g="\033[32m"; # green
+my $b="\033[34m"; # blue
+my $y="\033[33m"; # yellow
+my $e="\033[0m"; # end
+
+my @source;
+my $mainmenu = "";
+
+# Read source files
+sub addSrc {
+ my ($file) = @_;
+ my $F_IN;
+ open $F_IN, $file or die "Can't open $file\n";
+ while ( <$F_IN> ) {
+# print $_;
+ if ( /^\s*#/ ) {
+ } elsif ( /^\s?mainmenu\s+(.*?)\s*$/ ) {
+ $mainmenu = $1;
+ $mainmenu =~ s/^"(.*)"$/$1/;
+ } elsif ( /^\s?source\s+(.*?)\s*$/ ) {
+ ( my $src = $1 ) =~ s/^"(.*)"$/$1/;
+ if ( $src =~ /Kconfig/ ) {
+ addSrc($dir.$src);
+ } else {
+ push @source, $_;
+ }
+ } else {
+ while ( s/\\$// ) {
+ $_ .= <$F_IN>;
+ }
+ push @source, $_;
+ }
+ }
+ close $F_IN;
+}
+addSrc($dir."arch/$arch/Kconfig");
+
+# build hieralhical tree from sources
+sub noquote {
+ my ($text) = @_;
+ $text =~ s/^\s+//;
+ if ( $text =~ /^(['"])/ ) {
+ $text =~ s/$1(.*)$1/$1/;
+ }
+ return $text;
+}
+
+sub getoptions {
+ my ($option) = @_;
+ my $line;
+ my $help = 0;
+
+ while ( $line = shift @source ) {
+ last if $line =~ /^\s?(if\s+\S+(|.*\|\|.*|.*&&.*)|endif|\s*choice|\s*endchoice|\s*config\s+[0-9A-Za-z_]+|comment\s+.+|menu\s*.*|endmenu)(|\s+#.*)\s*$/;
+ if ( $help ) {
+ $$option{text} .= $line;
+ next;
+ }
+ if ( $line =~ /^\s*depends(\son|)\s(.*)/ ) {
+ if (defined $$option{depends}) {
+ $$option{depends} = "($$option{depends}) && ($2)";
+ } else {
+ $$option{depends} = $2;
+ }
+ } elsif ( $line =~ /^\s*select\s(.*)/ ) {
+ $$option{select} .= " " . $1;
+ } elsif ( $line =~ /^\s*prompt\s(.+?)(\s+if\s+(.*)|)$/ ) {
+ $$option{desc} = noquote($1);
+ if ( $3 ) {
+ if (defined $$option{depends}) {
+ $$option{depends} = "($$option{depends}) && ($3)";
+ } else {
+ $$option{depends} = $3;
+ }
+ }
+ } elsif ( $line =~ /^\s*(boolean|bool|tristate|int|string|hex)/ ) {
+ my $type = $1;
+ ( $$option{chtype} = $type ) =~ s/boolean/bool/;
+ if ( $line =~ /^\s*$type\s(.+?)(|\s+if\s+(.*))$/ ) {
+ $$option{desc} = noquote($1);
+ if ( $3 ) {
+ my $deps = $3;
+ if (defined $$option{depends}) {
+ $$option{depends} = "($$option{depends}) && ($deps)";
+ } else {
+ $$option{depends} = $deps;
+ }
+ }
+ }
+ } elsif ( $line =~ /^\s*def_(bool|tristate|int|string|hex)/ ) {
+ my $type = $1;
+ $$option{chtype} = $type;
+ if ( $line =~ /def_$type/ ) {
+ chomp $line;
+ $$option{desc} = "$line";
+ }
+
+ } elsif ( $line =~ /^\s*optional/ ) {
+ $$option{optional} = "optional";
+ } elsif ( $line =~ /^\s*(default|range).*/ ) {
+ $$option{text} .= $line;
+ unless ( defined $$option{desc} ) {
+ $$option{desc} = ""; #prevent from being deleted
+ }
+ } elsif ( $line =~ /^\s*(help|---help---)/ ) {
+ $help = 1;
+ } else {
+ warn "Lost line (getoptions): $line\n" if $line =~ /\S/;
+ }
+ }
+ $$option{select} =~ s/^ // if defined $$option{select};
+ unshift @source, $line;
+}
+
+sub mkmenu {
+ my ($end) = @_;
+ my $first;
+ my $current;
+ my $line;
+ while ( $line = shift @source ) {
+ last if $end and $line =~ /^\s*$end\s*(#.*|)$/;
+ my %option;
+ if ( $line =~ /^\s*(menu|)config\s+(.*)/ ) {
+ $option{type} = "config";
+ $option{name} = $2;
+ getoptions( \%option );
+ } elsif ( $line =~ /^\s?if\s(.*)/ ) {
+ $option{type} = "if";
+ $option{depends} = $1;
+ $option{body} = mkmenu("endif");
+ } elsif ( $line =~ /^\s*choice/ ) {
+ $option{type} = "choice";
+ getoptions( \%option );
+ $option{body} = mkmenu("endchoice");
+ } elsif ( $line =~ /^\s?menu\s?(.*)/ ) {
+ $option{type} = "menu";
+ $option{desc} = noquote($1);
+ getoptions( \%option );
+ $option{body} = mkmenu("endmenu");
+ } elsif ( $line =~ /\s?comment\s(.*)/ ) {
+ $option{type} = "comment";
+ $option{desc} = noquote($1);
+ getoptions( \%option );
+ } else {
+ warn "Lost line (mkmenu): $line\n" if $line =~ /\S/;
+ next;
+ }
+ $first = \%option unless defined $first;
+ $$current{next} = \%option if defined $current;
+ $current = \%option;
+ }
+ return $first;
+}
+
+my $menu = mkmenu("");
+undef @source;
+
+# read config file
+my %orig;
+my @orig;
+if ( -r $mainconf ) {
+ open F_IN, $mainconf;
+ while ( <F_IN> ) {
+ my $name;
+ if ( /^CONFIG_(.*?)=(.*)/ ) {
+ $orig{$1} = $2;
+ $name = $1;
+ } elsif ( /^# CONFIG_(.*?) is not set/ ) {
+ $orig{$1} = "n";
+ $name = $1;
+ }
+ push @orig, $name if defined $name;
+ }
+ close F_IN;
+} else {
+ die "$mainconf is not readable\n";
+}
+my %add;
+foreach my $file ( @addconf ) {
+ if ( -r $file ) {
+ open F_IN, $file;
+ while ( <F_IN> ) {
+ if ( /^CONFIG_(.*?)=(.*)/ ) {
+ $add{$1} = $2;
+ } elsif ( /^# CONFIG_(.*?) is not set/ ) {
+ $add{$1} = "n";
+ }
+ }
+ close F_IN;
+ } else {
+ die "$file is not readable\n";
+ }
+}
+
+my %config = ( %orig, %add );
+
+sub resolvedep {
+ my ($deps) = @_;
+# warn "$deps\n";
+ while ( $deps =~ /.*\((.*?)\)/ ) {
+ my $ask = $1;
+ my $resp = resolvedep($ask);
+# warn "QR: $ask -> $resp\n";
+ $ask =~ s/\|/\\\|/g;
+ $deps =~ s/\($ask\)/$resp/;
+ }
+# warn "$deps\n";
+ while ( $deps =~ /([A-Za-z0-9_]+)\s*!=\s*([A-Za-z0-9_]+)/ ) {
+ my ($opt1, $opt2) = ($1, $2);
+ my ($o1, $o2) = ($opt1, $opt2);
+ my $resp = 1;
+ if ( defined $config{$opt1} and $config{$opt1} ) {
+ $opt1 = $config{$opt1};
+ } elsif ( $opt1 !~ /^[mny]$/ ) {
+ $opt1 = "n";
+ }
+ if ( defined $config{$opt2} and $config{$opt2} ) {
+ $opt2 = $config{$opt2};
+ } elsif ( $opt2 !~ /^[mny]$/ ) {
+ $opt2 = "n";
+ }
+ if ( $opt1 eq $opt2 ) {
+ $resp = 0;
+ }
+# warn "$o1($opt1) != $o2($opt2) -> $resp\n";
+ $deps =~ s/$o1\s*!=\s*$o2/$resp/;
+ }
+# warn "$deps\n";
+ while ( $deps =~ /([A-Za-z0-9_]+)\s*=\s*([A-Za-z0-9_]+)/ ) {
+ my ($opt1, $opt2) = ($1, $2);
+ my ($o1, $o2) = ($opt1, $opt2);
+ my $resp = 0;
+ if ( defined $config{$opt1} and $config{$opt1} ) {
+ $opt1 = $config{$opt1};
+ }
+ if ( defined $config{$opt2} and $config{$opt2} ) {
+ $opt2 = $config{$opt2};
+ }
+ if ( $opt1 eq $opt2 ) {
+ $resp = 1;
+ }
+# warn "$o1($config{$o1}) = $o2($config{$o2}) -> $resp\n";
+ $deps =~ s/$o1\s*=\s*$o2/$resp/;
+ }
+# warn "$deps\n";
+ $deps =~ s/^m(\s.*|)$/1$1/;
+ while ( $deps =~ /([A-Za-z0-9_][A-Za-z0-9_]+)/ ) {
+ my $opt = $1;
+ my $resp = 0;
+ if ( defined $config{$opt} ) {
+ if ( $config{$opt} !~ /^[0n]$/ ) {
+ $resp = 1;
+ }
+ }
+# warn "$opt -> $resp\n";
+ $deps =~ s/$opt/$resp/;
+ }
+# warn "$deps\n";
+ $deps =~ s/!\s*0/1/g;
+# warn "$deps\n";
+ $deps =~ s/!\s*1/0/g;
+# warn "$deps\n";
+ while ( $deps =~ /([01])\s*&&\s*([01])/ ) {
+ my ($o1, $o2) = ($1, $2);
+ my $resp = 0;
+ if ( $o1 eq "1" and $o2 eq "1" ) {
+ $resp = 1;
+ }
+ $deps =~ s/$o1\s*&&\s*$o2/$resp/;
+ }
+# warn "$deps\n";
+ while ( $deps =~ /([01])\s*\|\|\s*([01])/ ) {
+ my ($o1, $o2) = ($1, $2);
+ my $resp = 1;
+ if ( $o1 eq "0" and $o2 eq "0" ) {
+ $resp = 0;
+ }
+ $deps =~ s/$o1\s*\|\|\s*$o2/$resp/;
+ }
+# warn "Return: $deps\n";
+ if ( $deps =~ /^1$/ ) {
+ return 1;
+ }
+ return 0;
+}
+
+print "$mainmenu\n";
+sub hiermenu {
+ my ($current, $step, $color) = @_;
+ do {
+ my $ns = " ";
+ $ns = "$color| $e" if defined $$current{next};
+ print $B . $step ."${color}|$e\n";
+ print $B . $step ."${color}+-$e";
+ print $y if $$current{type} eq "choice";
+ print $B.$b if $$current{type} eq "menu";
+ print $$current{type};
+ print " ($$current{name})" if defined $$current{name};
+ print " \"$$current{desc}\"" if defined $$current{desc};
+ print "$e\n";
+ if ( defined $$current{depends} ) {
+ my $c = $r;
+ if ( (not defined $$current{depends}) or resolvedep($$current{depends}) ) {
+ $c = $g;
+ }
+ print $B . $step . $ns . "`-$e ${c}DEPENDS: " . $$current{depends} . "$e\n";
+ }
+ if ( $$current{type} eq "config" ) {
+ if ( (not defined $$current{depends}) or resolvedep($$current{depends}) ) {
+ if ( defined $config{$$current{name}} ) {
+ print $B . $step . $ns . "`-$e RESP($$current{chtype}): " . $config{$$current{name}} ."\n";
+ } elsif ( not defined $$current{desc} ) {
+ print $B . $step . $ns . "`-$e RESP($$current{chtype}): ?\n";
+ } else {
+ if ( defined $$current{text} ) {
+ foreach my $line (split /\n/, $$current{text}) {
+ print $B . $step . $ns . "$e| " . $line ."\n";
+ }
+ }
+ if ( defined $$current{select} ) {
+ print $B . $step . $ns . "$e`- SELECTS: $$current{select}\n";
+ }
+
+ my $opt;
+ my $more = 1;
+ do {
+ my $type = $$current{chtype};
+ print $B . $step . $ns . "`-$e RESP($type): ";
+ $opt = <STDIN>;
+ chomp $opt;
+ if ( $opt eq "\033" ) {
+ warn "$r${B}skipping $$current{name}$e\n";
+ $more = 0;
+ } elsif ( $type eq "bool" ) {
+ $more = 0 if $opt =~ /^[ny]$/;
+ } elsif ( $type eq "tristate" ) {
+ $more = 0 if $opt =~ /^[nmy]$/;
+ } elsif ( $type eq "int" ) {
+ $more = 0 if $opt =~ /^[0-9]+$/;
+ } elsif ( $type eq "hex" ) {
+ $more = 0 if $opt =~ /^0x[0-9A-F]+$/;
+ } elsif ( $type eq "string" ) {
+ if ( $opt =~ /^".*"$/ ) {
+ $more = 0;
+ } else {
+ warn "String must be quoted: `\"\"'\n";
+ }
+ } else {
+ die "unknown choice type: $type\n";
+ }
+ } while ($more);
+ if ( $opt ne "\033" ) {
+ $orig{$$current{name}} = $opt;
+ if ( defined $$current{select} ) {
+ unless ( $opt =~ /^(n|0|0x0)$/ ) {
+ $opt = "y" unless $opt eq "m";
+ my $warn = 0;
+ foreach my $option (split /\s+/, $$current{select}) {
+ if ( (not defined $config{$option} ) or ($config{$option} eq "n") ) {
+ print $B . $step . $ns . "$e`- $r${B}WARNING:$e selecting `$option' (=$opt)\n";
+ $warn = 1;
+ $orig{$option} = $opt;
+ }
+ }
+ if ($warn) {
+ sleep 3;
+ }
+ }
+ }
+ %config = ( %orig, %add);
+ }
+ }
+ }
+ }
+ if ( defined $$current{body} ) {
+ if ( (not defined $$current{depends}) or resolvedep($$current{depends}) ) {
+ if ( $$current{type} eq "choice" ) {
+ hiermenu($$current{body}, "$step$ns", "$B$y");
+ } elsif ( $$current{type} eq "if" ) {
+ hiermenu($$current{body}, "$step$ns", "$B");
+ } elsif ( $$current{type} eq "menu" ) {
+ hiermenu($$current{body}, "$step$ns", "$B$b");
+ } else {
+ hiermenu($$current{body}, "$step$ns", $B);
+ }
+ }
+ }
+
+ } while ( (defined $$current{next}) and ($current = $$current{next}) );
+}
+if ( $ask ) {
+ hiermenu($menu,"", $B);
+}
+
+open C_NEW, "> $mainconf.new";
+sub savemenu {
+ my ($current) = @_;
+ do {
+ if ( $$current{type} eq "config" ) {
+ if ( defined $orig{$$current{name}} ) {
+ if ( $orig{$$current{name}} eq "n" ) {
+ print C_NEW "# CONFIG_$$current{name} is not set\n";
+ } else {
+ print C_NEW "CONFIG_$$current{name}=$orig{$$current{name}}\n";
+ }
+ delete $orig{$$current{name}};
+ }
+ }
+
+ if ( $$current{type} eq "comment" ) {
+ if ( (not defined $$current{depends}) or resolvedep($$current{depends}) ) {
+ print C_NEW "\n#\n# $$current{desc}\n#\n";
+ }
+ }
+ if ( defined $$current{body} ) {
+ if ( (not defined $$current{depends}) or resolvedep($$current{depends}) ) {
+ if ( defined $$current{desc} ) {
+ print C_NEW "\n#\n# $$current{desc}\n#\n";
+ }
+ }
+ savemenu($$current{body});
+ }
+
+ } while ( (defined $$current{next}) and ($current = $$current{next}) );
+}
+savemenu($menu);
+
+warn "LEFT:\n";
+print C_NEW "\n#\n# NON EXISTING OPTIONS\n#\n";
+foreach my $key ( @orig ) {
+ if ( defined $orig{$key} ) {
+ warn "$key=$orig{$key}\n";
+ if ( $orig{$key} eq "n" ) {
+ print C_NEW "# CONFIG_$key is not set\n";
+ } else {
+ print C_NEW "CONFIG_$key=$orig{$key}\n";
+ }
+ }
+}
+
+close C_NEW;
+-r "$mainconf.new" && print "$mainconf.new created\n";
================================================================
More information about the pld-cvs-commit
mailing list