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