History

Merge commit 'v2.6.35-rc3' into perf/core

Merge reason: Go from -rc1 base to -rc3 base, merge in fixes.

Ingo Molnar committed 16 years ago

Commit 646b1db2 parents 0f2c3de 7e27d6e1019 files · +83287 −7720Browse files

Showing the changes to scripts (42 of 1019 files). Show all

Unified · Split

42 files
  1. scripts/Makefile.build +1 −1
  2. scripts/Makefile.lib +1 −1
  3. scripts/Makefile.modbuiltin +5 −0
  4. scripts/checkincludes.pl +14 −10
  5. scripts/checkstack.pl +6 −10
  6. scripts/checkversion.pl +11 −12
  7. scripts/decodecode +35 −13
  8. scripts/export_report.pl +20 −17
  9. scripts/gen_initramfs_list.sh +2 −1
  10. scripts/genksyms/genksyms.c +3 −1
  11. scripts/headerdep.pl +1 −2
  12. scripts/headers_check.pl +6 −5
  13. scripts/headers_install.pl +10 −9
  14. scripts/kallsyms.c +4 −2
  15. scripts/kconfig/Makefile +15 −3
  16. scripts/kconfig/expr.c +25 −2
  17. scripts/kconfig/expr.h +2 −3
  18. scripts/kconfig/gconf.c +37 −76
  19. scripts/kconfig/gconf.glade +20 −6
  20. scripts/kconfig/lkc.h +6 −1
  21. scripts/kconfig/lkc_proto.h +4 −2
  22. scripts/kconfig/lxdialog/inputbox.c +2 −2
  23. scripts/kconfig/lxdialog/menubox.c +11 −11
  24. scripts/kconfig/mconf.c +19 −17
  25. scripts/kconfig/menu.c +26 −2
  26. scripts/kconfig/nconf.c +1568 −0
  27. scripts/kconfig/nconf.gui.c +617 −0
  28. scripts/kconfig/nconf.h +95 −0
  29. scripts/kconfig/symbol.c +18 −12
  30. scripts/kconfig/util.c +2 −0
  31. scripts/kconfig/zconf.tab.c_shipped +19 −6
  32. scripts/kconfig/zconf.y +19 −6
  33. scripts/markup_oops.pl +39 −15
  34. scripts/mkcompile_h +2 −3
  35. scripts/mod/modpost.c +88 −64
  36. scripts/namespace.pl +33 −32
  37. scripts/package/builddeb +2 −0
  38. scripts/package/mkspec +1 −1
  39. scripts/profile2linkerlist.pl +3 −5
  40. scripts/rt-tester/rt-tester.py +1 −1
  41. scripts/show_delta +1 −1
  42. scripts/tags.sh +30 −15
scripts/Makefile.build+1−1
@@ -82,7 +82,7 @@ ifneq ($(strip $(lib-y) $(lib-m) $(lib-n) $(lib-)),) · 81 unmodified lines
8282 lib-target := $(obj)/lib.a
8383 endif
8484
85−ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(lib-target)),)
85+ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(subdir-m) $(lib-target)),)
8686 builtin-target := $(obj)/built-in.o
8787 endif
8888
scripts/Makefile.lib+1−1
@@ -241,7 +241,7 @@ cmd_lzma = (cat $(filter-out FORCE,$^) | \ · 240 unmodified lines
241241 lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
242242 (rm -f $@ ; false)
243243
244−quiet_cmd_lzo = LZO $@
244+quiet_cmd_lzo = LZO $@
245245 cmd_lzo = (cat $(filter-out FORCE,$^) | \
246246 lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
247247 (rm -f $@ ; false)
scripts/Makefile.modbuiltin+5−0
@@ -14,6 +14,11 @@ __modbuiltin: · 13 unmodified lines
1414
1515 include scripts/Kbuild.include
1616
17+ifneq ($(KBUILD_SRC),)
18+# Create output directory if not already present
19+_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
20+endif
21+
1722 # The filename Kbuild has precedence over Makefile
1823 kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
1924 kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
scripts/checkincludes.pl+14−10
@@ -11,6 +11,8 @@ · 10 unmodified lines
1111 # you do have real dups and do not have them under #ifdef's. You
1212 # could also just review the results.
1313
14+use strict;
15+
1416 sub usage {
1517 print "Usage: checkincludes.pl [-r]\n";
1618 print "By default we just warn of duplicates\n";
@@ -35,23 +37,24 @@ if ($#ARGV >= 1) { · 18 unmodified lines
3537 }
3638 }
3739
38−foreach $file (@ARGV) {
39− open(FILE, $file) or die "Cannot open $file: $!.\n";
40+foreach my $file (@ARGV) {
41+ open(my $f, '<', $file)
42+ or die "Cannot open $file: $!.\n";
4043
4144 my %includedfiles = ();
4245 my @file_lines = ();
4346
44− while (<FILE>) {
47+ while (<$f>) {
4548 if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) {
4649 ++$includedfiles{$1};
4750 }
4851 push(@file_lines, $_);
4952 }
5053
51− close(FILE);
54+ close($f);
5255
5356 if (!$remove) {
54− foreach $filename (keys %includedfiles) {
57+ foreach my $filename (keys %includedfiles) {
5558 if ($includedfiles{$filename} > 1) {
5659 print "$file: $filename is included more than once.\n";
5760 }
@@ -59,27 +62,28 @@ foreach $file (@ARGV) { · 1 unmodified line
5962 next;
6063 }
6164
62− open(FILE,">$file") || die("Cannot write to $file: $!");
65+ open($f, '>', $file)
66+ or die("Cannot write to $file: $!");
6367
6468 my $dups = 0;
6569 foreach (@file_lines) {
6670 if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) {
67− foreach $filename (keys %includedfiles) {
71+ foreach my $filename (keys %includedfiles) {
6872 if ($1 eq $filename) {
6973 if ($includedfiles{$filename} > 1) {
7074 $includedfiles{$filename}--;
7175 $dups++;
7276 } else {
73− print FILE $_;
77+ print {$f} $_;
7478 }
7579 }
7680 }
7781 } else {
78− print FILE $_;
82+ print {$f} $_;
7983 }
8084 }
8185 if ($dups > 0) {
8286 print "$file: removed $dups duplicate includes\n";
8387 }
84− close(FILE);
88+ close($f);
8589 }
scripts/checkstack.pl+6−10
@@ -21,6 +21,8 @@ · 20 unmodified lines
2121 #
2222 # TODO : Port to all architectures (one regex per arch)
2323
24+use strict;
25+
2426 # check for arch
2527 #
2628 # $re is used for two matches:
@@ -104,19 +106,11 @@ my (@stack, $re, $dre, $x, $xs); · 77 unmodified lines
104106 }
105107 }
106108
107−sub bysize($) {
108− my ($asize, $bsize);
109− ($asize = $a) =~ s/.*: *(.*)$/$1/;
110− ($bsize = $b) =~ s/.*: *(.*)$/$1/;
111− $bsize <=> $asize
112−}
113−
114109 #
115110 # main()
116111 #
117112 my $funcre = qr/^$x* <(.*)>:$/;
118−my $func;
119−my $file, $lastslash;
113+my ($func, $file, $lastslash);
120114
121115 while (my $line = <STDIN>) {
122116 if ($line =~ m/$funcre/) {
@@ -173,4 +167,6 @@ while (my $line = <STDIN>) { · 50 unmodified lines
173167 }
174168 }
175169
176−print sort bysize @stack;
170+# Sort output by size (last field)
171+print sort { ($b =~ /:\t*(\d+)$/)[0] <=> ($a =~ /:\t*(\d+)$/)[0] } @stack;
172+
scripts/checkversion.pl+11−12
@@ -5,23 +5,22 @@ · 4 unmodified lines
55 # including <linux/version.h> that don't need it.
66 # Copyright (C) 2003, Randy Dunlap <rdunlap@xenotime.net>
77
8+use strict;
9+
810 $| = 1;
911
10−my $debugging = 0;
12+my $debugging;
1113
12−foreach $file (@ARGV)
13−{
14+foreach my $file (@ARGV) {
1415 # Open this file.
15− open(FILE, $file) || die "Can't open $file: $!\n";
16+ open( my $f, '<', $file )
17+ or die "Can't open $file: $!\n";
1618
1719 # Initialize variables.
18− my $fInComment = 0;
19− my $fInString = 0;
20− my $fUseVersion = 0;
20+ my ($fInComment, $fInString, $fUseVersion);
2121 my $iLinuxVersion = 0;
2222
23− LINE: while ( <FILE> )
24− {
23+ while (<$f>) {
2524 # Strip comments.
2625 $fInComment && (s+^.*?\*/+ +o ? ($fInComment = 0) : next);
2726 m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1)));
@@ -43,8 +42,8 @@ foreach $file (@ARGV) · 15 unmodified lines
4342 # Look for uses: LINUX_VERSION_CODE, KERNEL_VERSION, UTS_RELEASE
4443 if (($_ =~ /LINUX_VERSION_CODE/) || ($_ =~ /\WKERNEL_VERSION/)) {
4544 $fUseVersion = 1;
46− last LINE if $iLinuxVersion;
47− }
45+ last if $iLinuxVersion;
46+ }
4847 }
4948
5049 # Report used version IDs without include?
@@ -67,5 +66,5 @@ foreach $file (@ARGV) · 16 unmodified lines
6766 }
6867 }
6968
70− close(FILE);
69+ close($f);
7170 }
scripts/decodecode+35−13
@@ -7,7 +7,7 @@ · 6 unmodified lines
77 # AFLAGS=--32 decodecode < 386.oops
88
99 cleanup() {
10− rm -f $T $T.s $T.o $T.oo $T.aa $T.aaa
10+ rm -f $T $T.s $T.o $T.oo $T.aa $T.dis
1111 exit 1
1212 }
1313
@@ -39,6 +39,29 @@ fi · 25 unmodified lines
3939 echo $code
4040 code=`echo $code | sed -e 's/.*Code: //'`
4141
42+width=`expr index "$code" ' '`
43+width=$[($width-1)/2]
44+case $width in
45+1) type=byte ;;
46+2) type=2byte ;;
47+4) type=4byte ;;
48+esac
49+
50+disas() {
51+ ${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s &> /dev/null
52+
53+ if [ "$ARCH" == "arm" ]; then
54+ if [ $width == 2 ]; then
55+ OBJDUMPFLAGS="-M force-thumb"
56+ fi
57+
58+ ${CROSS_COMPILE}strip $1.o
59+ fi
60+
61+ ${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \
62+ grep -v "/tmp\|Disassembly\|\.text\|^$" &> $1.dis
63+}
64+
4265 marker=`expr index "$code" "\<"`
4366 if [ $marker -eq 0 ]; then
4467 marker=`expr index "$code" "\("`
@@ -49,26 +72,25 @@ if [ $marker -ne 0 ]; then · 4 unmodified lines
4972 echo All code >> $T.oo
5073 echo ======== >> $T.oo
5174 beforemark=`echo "$code"`
52− echo -n " .byte 0x" > $T.s
53− echo $beforemark | sed -e 's/ /,0x/g' | sed -e 's/<//g' | sed -e 's/>//g' >> $T.s
54− as $AFLAGS -o $T.o $T.s &> /dev/null
55− objdump -S $T.o | grep -v "/tmp" | grep -v "Disassembly" | grep -v "\.text" | grep -v "^$" &> $T.ooo
56− cat $T.ooo >> $T.oo
57− rm -f $T.o $T.s $T.ooo
75+ echo -n " .$type 0x" > $T.s
76+ echo $beforemark | sed -e 's/ /,0x/g; s/[<>()]//g' >> $T.s
77+ disas $T
78+ cat $T.dis >> $T.oo
79+ rm -f $T.o $T.s $T.dis
5880
5981 # and fix code at-and-after marker
6082 code=`echo "$code" | cut -c$((${marker} + 1))-`
6183 fi
6284 echo Code starting with the faulting instruction > $T.aa
6385 echo =========================================== >> $T.aa
64−code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g'`
65−echo -n " .byte 0x" > $T.s
86+code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g; s/[>)]$//'`
87+echo -n " .$type 0x" > $T.s
6688 echo $code >> $T.s
67−as $AFLAGS -o $T.o $T.s &> /dev/null
68−objdump -S $T.o | grep -v "Disassembly" | grep -v "/tmp" | grep -v "\.text" | grep -v "^$" &> $T.aaa
69−cat $T.aaa >> $T.aa
89+disas $T
90+cat $T.dis >> $T.aa
7091
71−faultline=`cat $T.aaa | head -1 | cut -d":" -f2`
92+faultline=`cat $T.dis | head -1 | cut -d":" -f2`
93+faultline=`echo "$faultline" | sed -e 's/\[/\\\[/g; s/\]/\\\]/g'`
7294
7395 cat $T.oo | sed -e "s/\($faultline\)/\*\1 <-- trapping instruction/g"
7496 echo
scripts/export_report.pl+20−17
@@ -49,10 +49,10 @@ sub usage { · 48 unmodified lines
4949 }
5050
5151 sub collectcfiles {
52− my @file = `cat .tmp_versions/*.mod | grep '.*\.ko\$'`;
53− @file = grep {s/\.ko/.mod.c/} @file;
54− chomp @file;
55− return @file;
52+ my @file
53+ = `cat .tmp_versions/*.mod | grep '.*\.ko\$' | sed s/\.ko$/.mod.c/`;
54+ chomp @file;
55+ return @file;
5656 }
5757
5858 my (%SYMBOL, %MODULE, %opt, @allcfiles);
@@ -71,37 +71,40 @@ if (not defined $opt{'k'}) { · 12 unmodified lines
7171 $opt{'k'} = "Module.symvers";
7272 }
7373
74−unless (open(MODULE_SYMVERS, $opt{'k'})) {
75− die "Sorry, cannot open $opt{'k'}: $!\n";
76−}
74+open (my $module_symvers, '<', $opt{'k'})
75+ or die "Sorry, cannot open $opt{'k'}: $!\n";
7776
7877 if (defined $opt{'o'}) {
79− unless (open(OUTPUT_HANDLE, ">$opt{'o'}")) {
80− die "Sorry, cannot open $opt{'o'} $!\n";
81− }
82− select OUTPUT_HANDLE;
78+ open (my $out, '>', $opt{'o'})
79+ or die "Sorry, cannot open $opt{'o'} $!\n";
80+
81+ select $out;
8382 }
83+
8484 #
8585 # collect all the symbols and their attributes from the
8686 # Module.symvers file
8787 #
88−while ( <MODULE_SYMVERS> ) {
88+while ( <$module_symvers> ) {
8989 chomp;
9090 my (undef, $symbol, $module, $gpl) = split;
9191 $SYMBOL { $symbol } = [ $module , "0" , $symbol, $gpl];
9292 }
93−close(MODULE_SYMVERS);
93+close($module_symvers);
9494
9595 #
9696 # collect the usage count of each symbol.
9797 #
9898 foreach my $thismod (@allcfiles) {
99− unless (open(MODULE_MODULE, $thismod)) {
100− print "Sorry, cannot open $thismod: $!\n";
99+ my $module;
100+
101+ unless (open ($module, '<', $thismod)) {
102+ warn "Sorry, cannot open $thismod: $!\n";
101103 next;
102104 }
105+
103106 my $state=0;
104− while ( <MODULE_MODULE> ) {
107+ while ( <$module> ) {
105108 chomp;
106109 if ($state == 0) {
107110 $state = 1 if ($_ =~ /static const struct modversion_info/);
@@ -124,7 +127,7 @@ foreach my $thismod (@allcfiles) { · 16 unmodified lines
124127 if ($state != 2) {
125128 print "WARNING:$thismod is not built with CONFIG_MODVERSION enabled\n";
126129 }
127− close(MODULE_MODULE);
130+ close($module);
128131 }
129132
130133 print "\tThis file reports the exported symbols usage patterns by in-tree\n",
scripts/gen_initramfs_list.sh+2−1
@@ -202,6 +202,7 @@ input_file() { · 201 unmodified lines
202202 print_mtime "$1" >> ${output}
203203 cat "$1" >> ${output}
204204 else
205+ echo "$1 \\"
205206 cat "$1" | while read type dir file perm ; do
206207 if [ "$type" == "file" ]; then
207208 echo "$file \\";
@@ -231,7 +232,7 @@ arg="$1" · 23 unmodified lines
231232 case "$arg" in
232233 "-l") # files included in initramfs - used by kbuild
233234 dep_list="list_"
234− echo "deps_initramfs := \\"
235+ echo "deps_initramfs := $0 \\"
235236 shift
236237 ;;
237238 "-o") # generate compressed cpio image named $1
scripts/genksyms/genksyms.c+3−1
@@ -758,8 +758,10 @@ int main(int argc, char **argv) · 757 unmodified lines
758758 /* setlinebuf(debugfile); */
759759 }
760760
761− if (flag_reference)
761+ if (flag_reference) {
762762 read_reference(ref_file);
763+ fclose(ref_file);
764+ }
763765
764766 yyparse();
765767
scripts/headerdep.pl+1−2
@@ -80,8 +80,7 @@ sub search { · 79 unmodified lines
8080 my $path = "$i/$filename";
8181 return $path if -f $path;
8282 }
83−
84− return undef;
83+ return;
8584 }
8685
8786 sub parse_all {
scripts/headers_check.pl+6−5
@@ -28,11 +28,12 @@ my $lineno = 0; · 27 unmodified lines
2828 my $filename;
2929
3030 foreach my $file (@files) {
31− local *FH;
3231 $filename = $file;
33− open(FH, "<$filename") or die "$filename: $!\n";
32+
33+ open(my $fh, '<', $filename)
34+ or die "$filename: $!\n";
3435 $lineno = 0;
35− while ($line = <FH>) {
36+ while ($line = <$fh>) {
3637 $lineno++;
3738 &check_include();
3839 &check_asm_types();
@@ -40,7 +41,7 @@ foreach my $file (@files) { · 1 unmodified line
4041 &check_declarations();
4142 # Dropped for now. Too much noise &check_config();
4243 }
43− close FH;
44+ close $fh;
4445 }
4546 exit $ret;
4647
@@ -78,7 +79,7 @@ sub check_config · 31 unmodified lines
7879 }
7980
8081 my $linux_asm_types;
81−sub check_asm_types()
82+sub check_asm_types
8283 {
8384 if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) {
8485 return;
scripts/headers_install.pl+10−9
@@ -23,13 +23,13 @@ my ($readdir, $installdir, $arch, @files) = @ARGV; · 22 unmodified lines
2323 my $unifdef = "scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__";
2424
2525 foreach my $file (@files) {
26− local *INFILE;
27− local *OUTFILE;
2826 my $tmpfile = "$installdir/$file.tmp";
29− open(INFILE, "<$readdir/$file")
30− or die "$readdir/$file: $!\n";
31− open(OUTFILE, ">$tmpfile") or die "$tmpfile: $!\n";
32− while (my $line = <INFILE>) {
27+
28+ open(my $in, '<', "$readdir/$file")
29+ or die "$readdir/$file: $!\n";
30+ open(my $out, '>', $tmpfile)
31+ or die "$tmpfile: $!\n";
32+ while (my $line = <$in>) {
3333 $line =~ s/([\s(])__user\s/$1/g;
3434 $line =~ s/([\s(])__force\s/$1/g;
3535 $line =~ s/([\s(])__iomem\s/$1/g;
@@ -39,10 +39,11 @@ foreach my $file (@files) { · 3 unmodified lines
3939 $line =~ s/(^|\s)(inline)\b/$1__$2__/g;
4040 $line =~ s/(^|\s)(asm)\b(\s|[(]|$)/$1__$2__$3/g;
4141 $line =~ s/(^|\s|[(])(volatile)\b(\s|[(]|$)/$1__$2__$3/g;
42− printf OUTFILE "%s", $line;
42+ printf {$out} "%s", $line;
4343 }
44− close OUTFILE;
45− close INFILE;
44+ close $out;
45+ close $in;
46+
4647 system $unifdef . " $tmpfile > $installdir/$file";
4748 unlink $tmpfile;
4849 }
scripts/kallsyms.c+4−2
@@ -108,8 +108,10 @@ static int read_symbol(FILE *in, struct sym_entry *s) · 107 unmodified lines
108108 rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str);
109109 if (rc != 3) {
110110 if (rc != EOF) {
111− /* skip line */
112− fgets(str, 500, in);
111+ /* skip line. sym is used as dummy to
112+ * shut of "warn_unused_result" warning.
113+ */
114+ sym = fgets(str, 500, in);
113115 }
114116 return -1;
115117 }
scripts/kconfig/Makefile+15−3
@@ -23,6 +23,9 @@ menuconfig: $(obj)/mconf · 22 unmodified lines
2323 config: $(obj)/conf
2424 $< $(Kconfig)
2525
26+nconfig: $(obj)/nconf
27+ $< $(Kconfig)
28+
2629 oldconfig: $(obj)/conf
2730 $< -o $(Kconfig)
2831
@@ -120,6 +123,7 @@ endif · 91 unmodified lines
120123 # Help text used by make help
121124 help:
122125 @echo ' config - Update current config utilising a line-oriented program'
126+ @echo ' nconfig - Update current config utilising a ncurses menu based program'
123127 @echo ' menuconfig - Update current config utilising a menu based program'
124128 @echo ' xconfig - Update current config utilising a QT based front-end'
125129 @echo ' gconfig - Update current config utilising a GTK based front-end'
@@ -147,6 +151,8 @@ HOST_EXTRACFLAGS += -DLOCALE · 21 unmodified lines
147151 # ===========================================================================
148152 # Shared Makefile for the various kconfig executables:
149153 # conf: Used for defconfig, oldconfig and related targets
154+# nconf: Used for the nconfig target.
155+# Utilizes ncurses
150156 # mconf: Used for the menuconfig target
151157 # Utilizes the lxdialog package
152158 # qconf: Used for the xconfig target
@@ -159,11 +165,16 @@ lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o · 6 unmodified lines
159165 lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o
160166
161167 conf-objs := conf.o zconf.tab.o
162−mconf-objs := mconf.o zconf.tab.o $(lxdialog)
168+mconf-objs := mconf.o zconf.tab.o $(lxdialog)
169+nconf-objs := nconf.o zconf.tab.o nconf.gui.o
163170 kxgettext-objs := kxgettext.o zconf.tab.o
164171
165172 hostprogs-y := conf qconf gconf kxgettext
166173
174+ifeq ($(MAKECMDGOALS),nconfig)
175+ hostprogs-y += nconf
176+endif
177+
167178 ifeq ($(MAKECMDGOALS),menuconfig)
168179 hostprogs-y += mconf
169180 endif
@@ -187,7 +198,7 @@ endif · 17 unmodified lines
187198
188199 clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \
189200 .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h
190−clean-files += mconf qconf gconf
201+clean-files += mconf qconf gconf nconf
191202 clean-files += config.pot linux.pot
192203
193204 # Check that we have the required ncurses stuff installed for lxdialog (menuconfig)
@@ -208,10 +219,11 @@ HOSTCFLAGS_zconf.tab.o := -I$(src) · 14 unmodified lines
208219 HOSTLOADLIBES_qconf = $(KC_QT_LIBS) -ldl
209220 HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK
210221
211−HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0`
222+HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` -ldl
212223 HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \
213224 -D LKC_DIRECT_LINK
214225
226+HOSTLOADLIBES_nconf = -lmenu -lpanel -lncurses
215227 $(obj)/qconf.o: $(obj)/.tmp_qtcheck
216228
217229 ifeq ($(qconf-target),1)
scripts/kconfig/expr.c+25−2
@@ -1097,9 +1097,32 @@ void expr_fprint(struct expr *e, FILE *out) · 1096 unmodified lines
10971097
10981098 static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
10991099 {
1100− str_append((struct gstr*)data, str);
1100+ struct gstr *gs = (struct gstr*)data;
1101+ const char *sym_str = NULL;
1102+
1103+ if (sym)
1104+ sym_str = sym_get_string_value(sym);
1105+
1106+ if (gs->max_width) {
1107+ unsigned extra_length = strlen(str);
1108+ const char *last_cr = strrchr(gs->s, '\n');
1109+ unsigned last_line_length;
1110+
1111+ if (sym_str)
1112+ extra_length += 4 + strlen(sym_str);
1113+
1114+ if (!last_cr)
1115+ last_cr = gs->s;
1116+
1117+ last_line_length = strlen(gs->s) - (last_cr - gs->s);
1118+
1119+ if ((last_line_length + extra_length) > gs->max_width)
1120+ str_append(gs, "\\\n");
1121+ }
1122+
1123+ str_append(gs, str);
11011124 if (sym)
1102− str_printf((struct gstr*)data, " [=%s]", sym_get_string_value(sym));
1125+ str_printf(gs, " [=%s]", sym_str);
11031126 }
11041127
11051128 void expr_gstr_print(struct expr *e, struct gstr *gs)
scripts/kconfig/expr.h+2−3
@@ -86,7 +86,7 @@ struct symbol { · 85 unmodified lines
8686 struct expr_value rev_dep;
8787 };
8888
89−#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
89+#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
9090
9191 #define SYMBOL_CONST 0x0001 /* symbol is const */
9292 #define SYMBOL_CHECK 0x0008 /* used during dependency checking */
@@ -108,8 +108,7 @@ struct symbol { · 15 unmodified lines
108108 #define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */
109109
110110 #define SYMBOL_MAXLENGTH 256
111−#define SYMBOL_HASHSIZE 257
112−#define SYMBOL_HASHMASK 0xff
111+#define SYMBOL_HASHSIZE 9973
113112
114113 /* A property represent the config options that can be associated
115114 * with a config "symbol".
scripts/kconfig/gconf.c+37−76
@@ -30,13 +30,16 @@ enum { · 29 unmodified lines
3030 SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW
3131 };
3232
33+enum {
34+ OPT_NORMAL, OPT_ALL, OPT_PROMPT
35+};
36+
3337 static gint view_mode = FULL_VIEW;
3438 static gboolean show_name = TRUE;
3539 static gboolean show_range = TRUE;
3640 static gboolean show_value = TRUE;
37−static gboolean show_all = FALSE;
38−static gboolean show_debug = FALSE;
3941 static gboolean resizeable = FALSE;
42+static int opt_mode = OPT_NORMAL;
4043
4144 GtkWidget *main_wnd = NULL;
4245 GtkWidget *tree1_w = NULL; // left frame
@@ -76,36 +79,7 @@ static void conf_changed(void); · 33 unmodified lines
7679
7780 /* Helping/Debugging Functions */
7881
79−
80−const char *dbg_print_stype(int val)
81−{
82− static char buf[256];
83−
84− bzero(buf, 256);
85−
86− if (val == S_UNKNOWN)
87− strcpy(buf, "unknown");
88− if (val == S_BOOLEAN)
89− strcpy(buf, "boolean");
90− if (val == S_TRISTATE)
91− strcpy(buf, "tristate");
92− if (val == S_INT)
93− strcpy(buf, "int");
94− if (val == S_HEX)
95− strcpy(buf, "hex");
96− if (val == S_STRING)
97− strcpy(buf, "string");
98− if (val == S_OTHER)
99− strcpy(buf, "other");
100−
101−#ifdef DEBUG
102− printf("%s", buf);
103−#endif
104−
105− return buf;
106−}
107−
108−const char *dbg_print_flags(int val)
82+const char *dbg_sym_flags(int val)
10983 {
11084 static char buf[256];
11185
@@ -131,40 +105,10 @@ const char *dbg_print_flags(int val) · 19 unmodified lines
131105 strcat(buf, "auto/");
132106
133107 buf[strlen(buf) - 1] = '\0';
134−#ifdef DEBUG
135− printf("%s", buf);
136−#endif
137−
138− return buf;
139−}
140−
141−const char *dbg_print_ptype(int val)
142−{
143− static char buf[256];
144−
145− bzero(buf, 256);
146−
147− if (val == P_UNKNOWN)
148− strcpy(buf, "unknown");
149− if (val == P_PROMPT)
150− strcpy(buf, "prompt");
151− if (val == P_COMMENT)
152− strcpy(buf, "comment");
153− if (val == P_MENU)
154− strcpy(buf, "menu");
155− if (val == P_DEFAULT)
156− strcpy(buf, "default");
157− if (val == P_CHOICE)
158− strcpy(buf, "choice");
159−
160−#ifdef DEBUG
161− printf("%s", buf);
162−#endif
163108
164109 return buf;
165110 }
166111
167−
168112 void replace_button_icon(GladeXML * xml, GdkDrawable * window,
169113 GtkStyle * style, gchar * btn_name, gchar ** xpm)
170114 {
@@ -697,20 +641,29 @@ void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data) · 526 unmodified lines
697641
698642
699643 void
700−on_show_all_options1_activate(GtkMenuItem * menuitem, gpointer user_data)
644+on_set_option_mode1_activate(GtkMenuItem *menuitem, gpointer user_data)
701645 {
702− show_all = GTK_CHECK_MENU_ITEM(menuitem)->active;
646+ opt_mode = OPT_NORMAL;
647+ gtk_tree_store_clear(tree2);
648+ display_tree(&rootmenu); /* instead of update_tree to speed-up */
649+}
650+
703651
652+void
653+on_set_option_mode2_activate(GtkMenuItem *menuitem, gpointer user_data)
654+{
655+ opt_mode = OPT_ALL;
704656 gtk_tree_store_clear(tree2);
705− display_tree(&rootmenu); // instead of update_tree to speed-up
657+ display_tree(&rootmenu); /* instead of update_tree to speed-up */
706658 }
707659
708660
709661 void
710−on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data)
662+on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data)
711663 {
712− show_debug = GTK_CHECK_MENU_ITEM(menuitem)->active;
713− update_tree(&rootmenu, NULL);
664+ opt_mode = OPT_PROMPT;
665+ gtk_tree_store_clear(tree2);
666+ display_tree(&rootmenu); /* instead of update_tree to speed-up */
714667 }
715668
716669
@@ -1163,7 +1116,10 @@ static gchar **fill_row(struct menu *menu) · 446 unmodified lines
11631116 g_strdup_printf("%s %s", _(menu_get_prompt(menu)),
11641117 sym && sym_has_value(sym) ? "(NEW)" : "");
11651118
1166− if (show_all && !menu_is_visible(menu))
1119+ if (opt_mode == OPT_ALL && !menu_is_visible(menu))
1120+ row[COL_COLOR] = g_strdup("DarkGray");
1121+ else if (opt_mode == OPT_PROMPT &&
1122+ menu_has_prompt(menu) && !menu_is_visible(menu))
11671123 row[COL_COLOR] = g_strdup("DarkGray");
11681124 else
11691125 row[COL_COLOR] = g_strdup("Black");
@@ -1386,16 +1342,19 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) · 216 unmodified lines
13861342 menu2 ? menu_get_prompt(menu2) : "nil");
13871343 #endif
13881344
1389− if (!menu_is_visible(child1) && !show_all) { // remove node
1345+ if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) ||
1346+ (opt_mode == OPT_PROMPT && !menu_has_prompt(child1))) {
1347+
1348+ /* remove node */
13901349 if (gtktree_iter_find_node(dst, menu1) != NULL) {
13911350 memcpy(&tmp, child2, sizeof(GtkTreeIter));
13921351 valid = gtk_tree_model_iter_next(model2,
13931352 child2);
13941353 gtk_tree_store_remove(tree2, &tmp);
13951354 if (!valid)
1396− return; // next parent
1355+ return; /* next parent */
13971356 else
1398− goto reparse; // next child
1357+ goto reparse; /* next child */
13991358 } else
14001359 continue;
14011360 }
@@ -1464,17 +1423,19 @@ static void display_tree(struct menu *menu) · 62 unmodified lines
14641423 && (tree == tree2))
14651424 continue;
14661425
1467− if (menu_is_visible(child) || show_all)
1426+ if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) ||
1427+ (opt_mode == OPT_PROMPT && menu_has_prompt(child)) ||
1428+ (opt_mode == OPT_ALL))
14681429 place_node(child, fill_row(child));
14691430 #ifdef DEBUG
14701431 printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
14711432 printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : "");
1472− dbg_print_ptype(ptype);
1433+ printf("%s", prop_get_type_name(ptype));
14731434 printf(" | ");
14741435 if (sym) {
1475− dbg_print_stype(sym->type);
1436+ printf("%s", sym_type_name(sym->type));
14761437 printf(" | ");
1477− dbg_print_flags(sym->flags);
1438+ printf("%s", dbg_sym_flags(sym->flags));
14781439 printf("\n");
14791440 } else
14801441 printf("\n");
scripts/kconfig/gconf.glade+20−6
@@ -190,26 +190,40 @@ · 189 unmodified lines
190190 </child>
191191
192192 <child>
193− <widget class="GtkCheckMenuItem" id="show_all_options1">
193+ <widget class="GtkRadioMenuItem" id="set_option_mode1">
194+ <property name="visible">True</property>
195+ <property name="tooltip" translatable="yes">Show normal options</property>
196+ <property name="label" translatable="yes">Show normal options</property>
197+ <property name="use_underline">True</property>
198+ <property name="active">True</property>
199+ <signal name="activate" handler="on_set_option_mode1_activate"/>
200+ </widget>
201+ </child>
202+
203+ <child>
204+ <widget class="GtkRadioMenuItem" id="set_option_mode2">
194205 <property name="visible">True</property>
195206 <property name="tooltip" translatable="yes">Show all options</property>
196207 <property name="label" translatable="yes">Show all _options</property>
197208 <property name="use_underline">True</property>
198209 <property name="active">False</property>
199− <signal name="activate" handler="on_show_all_options1_activate"/>
210+ <property name="group">set_option_mode1</property>
211+ <signal name="activate" handler="on_set_option_mode2_activate"/>
200212 </widget>
201213 </child>
202214
203215 <child>
204− <widget class="GtkCheckMenuItem" id="show_debug_info1">
216+ <widget class="GtkRadioMenuItem" id="set_option_mode3">
205217 <property name="visible">True</property>
206− <property name="tooltip" translatable="yes">Show masked options</property>
207− <property name="label" translatable="yes">Show _debug info</property>
218+ <property name="tooltip" translatable="yes">Show all options with prompts</property>
219+ <property name="label" translatable="yes">Show all prompt options</property>
208220 <property name="use_underline">True</property>
209221 <property name="active">False</property>
210− <signal name="activate" handler="on_show_debug_info1_activate"/>
222+ <property name="group">set_option_mode1</property>
223+ <signal name="activate" handler="on_set_option_mode3_activate"/>
211224 </widget>
212225 </child>
226+
213227 </widget>
214228 </child>
215229 </widget>
scripts/kconfig/lkc.h+6−1
@@ -84,7 +84,7 @@ void conf_set_all_new_symbols(enum conf_def_mode mode); · 83 unmodified lines
8484 void kconfig_load(void);
8585
8686 /* menu.c */
87−void menu_init(void);
87+void _menu_init(void);
8888 void menu_warn(struct menu *menu, const char *fmt, ...);
8989 struct menu *menu_add_menu(void);
9090 void menu_end_menu(void);
@@ -106,6 +106,11 @@ int file_write_dep(const char *name); · 15 unmodified lines
106106 struct gstr {
107107 size_t len;
108108 char *s;
109+ /*
110+ * when max_width is not zero long lines in string s (if any) get
111+ * wrapped not to exceed the max_width value
112+ */
113+ int max_width;
109114 };
110115 struct gstr str_new(void);
111116 struct gstr str_assign(const char *s);
scripts/kconfig/lkc_proto.h+4−2
@@ -11,13 +11,15 @@ P(conf_set_changed_callback, void,(void (*fn)(void))); · 10 unmodified lines
1111 /* menu.c */
1212 P(rootmenu,struct menu,);
1313
14−P(menu_is_visible,bool,(struct menu *menu));
14+P(menu_is_visible, bool, (struct menu *menu));
15+P(menu_has_prompt, bool, (struct menu *menu));
1516 P(menu_get_prompt,const char *,(struct menu *menu));
1617 P(menu_get_root_menu,struct menu *,(struct menu *menu));
1718 P(menu_get_parent_menu,struct menu *,(struct menu *menu));
1819 P(menu_has_help,bool,(struct menu *menu));
1920 P(menu_get_help,const char *,(struct menu *menu));
20−P(get_symbol_str,void,(struct gstr *r, struct symbol *sym));
21+P(get_symbol_str, void, (struct gstr *r, struct symbol *sym));
22+P(get_relations_str, struct gstr, (struct symbol **sym_arr));
2123 P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help));
2224
2325 /* symbol.c */
scripts/kconfig/lxdialog/inputbox.c+2−2
@@ -180,7 +180,7 @@ do_resize: · 179 unmodified lines
180180 case KEY_LEFT:
181181 switch (button) {
182182 case -1:
183− button = 1; /* Indicates "Cancel" button is selected */
183+ button = 1; /* Indicates "Help" button is selected */
184184 print_buttons(dialog, height, width, 1);
185185 break;
186186 case 0:
@@ -204,7 +204,7 @@ do_resize: · 17 unmodified lines
204204 print_buttons(dialog, height, width, 0);
205205 break;
206206 case 0:
207− button = 1; /* Indicates "Cancel" button is selected */
207+ button = 1; /* Indicates "Help" button is selected */
208208 print_buttons(dialog, height, width, 1);
209209 break;
210210 case 1:
scripts/kconfig/lxdialog/menubox.c+11−11
@@ -383,6 +383,10 @@ do_resize: · 382 unmodified lines
383383 case 'n':
384384 case 'm':
385385 case '/':
386+ case 'h':
387+ case '?':
388+ case 'z':
389+ case '\n':
386390 /* save scroll info */
387391 *s_scroll = scroll;
388392 delwin(menu);
@@ -390,8 +394,10 @@ do_resize: · 1 unmodified line
390394 item_set(scroll + choice);
391395 item_set_selected(1);
392396 switch (key) {
397+ case 'h':
398+ case '?':
399+ return 2;
393400 case 's':
394− return 3;
395401 case 'y':
396402 return 3;
397403 case 'n':
@@ -402,18 +408,12 @@ do_resize: · 4 unmodified lines
402408 return 6;
403409 case '/':
404410 return 7;
411+ case 'z':
412+ return 8;
413+ case '\n':
414+ return button;
405415 }
406416 return 0;
407− case 'h':
408− case '?':
409− button = 2;
410− case '\n':
411− *s_scroll = scroll;
412− delwin(menu);
413− delwin(dialog);
414− item_set(scroll + choice);
415− item_set_selected(1);
416− return button;
417417 case 'e':
418418 case 'x':
419419 key = KEY_ESC;
scripts/kconfig/mconf.c+19−17
@@ -67,13 +67,15 @@ static const char mconf_readme[] = N_( · 66 unmodified lines
6767 " there is a delayed response which you may find annoying.\n"
6868 "\n"
6969 " Also, the <TAB> and cursor keys will cycle between <Select>,\n"
70−" <Exit> and <Help>\n"
70+" <Exit> and <Help>.\n"
7171 "\n"
7272 "o To get help with an item, use the cursor keys to highlight <Help>\n"
73−" and Press <ENTER>.\n"
73+" and press <ENTER>.\n"
7474 "\n"
7575 " Shortcut: Press <H> or <?>.\n"
7676 "\n"
77+"o To show hidden options, press <Z>.\n"
78+"\n"
7779 "\n"
7880 "Radiolists (Choice lists)\n"
7981 "-----------\n"
@@ -272,6 +274,7 @@ static int indent; · 192 unmodified lines
272274 static struct menu *current_menu;
273275 static int child_count;
274276 static int single_menu_mode;
277+static int show_all_options;
275278
276279 static void conf(struct menu *menu);
277280 static void conf_choice(struct menu *menu);
@@ -282,19 +285,6 @@ static void show_textbox(const char *title, const char *text, int r, int c); · 4 unmodified lines
282285 static void show_helptext(const char *title, const char *text);
283286 static void show_help(struct menu *menu);
284287
285−static struct gstr get_relations_str(struct symbol **sym_arr)
286−{
287− struct symbol *sym;
288− struct gstr res = str_new();
289− int i;
290−
291− for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
292− get_symbol_str(&res, sym);
293− if (!i)
294− str_append(&res, _("No matches found.\n"));
295− return res;
296−}
297−
298288 static char filename[PATH_MAX+1];
299289 static void set_config_filename(const char *config_filename)
300290 {
@@ -359,8 +349,16 @@ static void build_conf(struct menu *menu) · 58 unmodified lines
359349 int type, tmp, doint = 2;
360350 tristate val;
361351 char ch;
362−
363− if (!menu_is_visible(menu))
352+ bool visible;
353+
354+ /*
355+ * note: menu_is_visible() has side effect that it will
356+ * recalc the value of the symbol.
357+ */
358+ visible = menu_is_visible(menu);
359+ if (show_all_options && !menu_has_prompt(menu))
360+ return;
361+ else if (!show_all_options && !visible)
364362 return;
365363
366364 sym = menu->sym;
@@ -619,6 +617,9 @@ static void conf(struct menu *menu) · 252 unmodified lines
619617 case 7:
620618 search_conf();
621619 break;
620+ case 8:
621+ show_all_options = !show_all_options;
622+ break;
622623 }
623624 }
624625 }
@@ -638,6 +639,7 @@ static void show_help(struct menu *menu) · 13 unmodified lines
638639 {
639640 struct gstr help = str_new();
640641
642+ help.max_width = getmaxx(stdscr) - 10;
641643 menu_get_ext_help(menu, &help);
642644
643645 show_helptext(_(menu_get_prompt(menu)), str_get(&help));
scripts/kconfig/menu.c+26−2
@@ -38,7 +38,7 @@ static void prop_warn(struct property *prop, const char *fmt, ...) · 37 unmodified lines
3838 va_end(ap);
3939 }
4040
41−void menu_init(void)
41+void _menu_init(void)
4242 {
4343 current_entry = current_menu = &rootmenu;
4444 last_entry_ptr = &rootmenu.list;
@@ -197,7 +197,7 @@ static void sym_check_prop(struct symbol *sym) · 152 unmodified lines
197197 if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
198198 prop->expr->type != E_SYMBOL)
199199 prop_warn(prop,
200− "default for config symbol '%'"
200+ "default for config symbol '%s'"
201201 " must be a single symbol", sym->name);
202202 break;
203203 case P_SELECT:
@@ -390,6 +390,13 @@ void menu_finalize(struct menu *parent) · 186 unmodified lines
390390 }
391391 }
392392
393+bool menu_has_prompt(struct menu *menu)
394+{
395+ if (!menu->prompt)
396+ return false;
397+ return true;
398+}
399+
393400 bool menu_is_visible(struct menu *menu)
394401 {
395402 struct menu *child;
@@ -398,6 +405,7 @@ bool menu_is_visible(struct menu *menu) · 2 unmodified lines
398405
399406 if (!menu->prompt)
400407 return false;
408+
401409 sym = menu->sym;
402410 if (sym) {
403411 sym_calc_value(sym);
@@ -407,12 +415,14 @@ bool menu_is_visible(struct menu *menu) · 3 unmodified lines
407415
408416 if (visible != no)
409417 return true;
418+
410419 if (!sym || sym_get_tristate_value(menu->sym) == no)
411420 return false;
412421
413422 for (child = menu->list; child; child = child->next)
414423 if (menu_is_visible(child))
415424 return true;
425+
416426 return false;
417427 }
418428
@@ -515,6 +525,20 @@ void get_symbol_str(struct gstr *r, struct symbol *sym) · 96 unmodified lines
515525 str_append(r, "\n\n");
516526 }
517527
528+struct gstr get_relations_str(struct symbol **sym_arr)
529+{
530+ struct symbol *sym;
531+ struct gstr res = str_new();
532+ int i;
533+
534+ for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
535+ get_symbol_str(&res, sym);
536+ if (!i)
537+ str_append(&res, _("No matches found.\n"));
538+ return res;
539+}
540+
541+
518542 void menu_get_ext_help(struct menu *menu, struct gstr *help)
519543 {
520544 struct symbol *sym = menu->sym;
scripts/kconfig/nconf.c+1568−0
@@ -0,0 +1,1568 @@
1+/*
2+ * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
3+ * Released under the terms of the GNU GPL v2.0.
4+ *
5+ * Derived from menuconfig.
6+ *
7+ */
8+#define LKC_DIRECT_LINK
9+#include "lkc.h"
10+#include "nconf.h"
11+
12+static const char nconf_readme[] = N_(
13+"Overview\n"
14+"--------\n"
15+"Some kernel features may be built directly into the kernel.\n"
16+"Some may be made into loadable runtime modules. Some features\n"
17+"may be completely removed altogether. There are also certain\n"
18+"kernel parameters which are not really features, but must be\n"
19+"entered in as decimal or hexadecimal numbers or possibly text.\n"
20+"\n"
21+"Menu items beginning with following braces represent features that\n"
22+" [ ] can be built in or removed\n"
23+" < > can be built in, modularized or removed\n"
24+" { } can be built in or modularized (selected by other feature)\n"
25+" - - are selected by other feature,\n"
26+" XXX cannot be selected. use Symbol Info to find out why,\n"
27+"while *, M or whitespace inside braces means to build in, build as\n"
28+"a module or to exclude the feature respectively.\n"
29+"\n"
30+"To change any of these features, highlight it with the cursor\n"
31+"keys and press <Y> to build it in, <M> to make it a module or\n"
32+"<N> to removed it. You may also press the <Space Bar> to cycle\n"
33+"through the available options (ie. Y->N->M->Y).\n"
34+"\n"
35+"Some additional keyboard hints:\n"
36+"\n"
37+"Menus\n"
38+"----------\n"
39+"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
40+" you wish to change use <Enter> or <Space>. Goto submenu by \n"
41+" pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n"
42+" Submenus are designated by \"--->\".\n"
43+"\n"
44+" Shortcut: Press the option's highlighted letter (hotkey).\n"
45+" Pressing a hotkey more than once will sequence\n"
46+" through all visible items which use that hotkey.\n"
47+"\n"
48+" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
49+" unseen options into view.\n"
50+"\n"
51+"o To exit a menu use the just press <ESC> <F5> <F8> or <left-arrow>.\n"
52+"\n"
53+"o To get help with an item, press <F1>\n"
54+" Shortcut: Press <h> or <?>.\n"
55+"\n"
56+"\n"
57+"Radiolists (Choice lists)\n"
58+"-----------\n"
59+"o Use the cursor keys to select the option you wish to set and press\n"
60+" <S> or the <SPACE BAR>.\n"
61+"\n"
62+" Shortcut: Press the first letter of the option you wish to set then\n"
63+" press <S> or <SPACE BAR>.\n"
64+"\n"
65+"o To see available help for the item, press <F1>\n"
66+" Shortcut: Press <H> or <?>.\n"
67+"\n"
68+"\n"
69+"Data Entry\n"
70+"-----------\n"
71+"o Enter the requested information and press <ENTER>\n"
72+" If you are entering hexadecimal values, it is not necessary to\n"
73+" add the '0x' prefix to the entry.\n"
74+"\n"
75+"o For help, press <F1>.\n"
76+"\n"
77+"\n"
78+"Text Box (Help Window)\n"
79+"--------\n"
80+"o Use the cursor keys to scroll up/down/left/right. The VI editor\n"
81+" keys h,j,k,l function here as do <SPACE BAR> for those\n"
82+" who are familiar with less and lynx.\n"
83+"\n"
84+"o Press <Enter>, <F1>, <F5>, <F7> or <Esc> to exit.\n"
85+"\n"
86+"\n"
87+"Alternate Configuration Files\n"
88+"-----------------------------\n"
89+"nconfig supports the use of alternate configuration files for\n"
90+"those who, for various reasons, find it necessary to switch\n"
91+"between different kernel configurations.\n"
92+"\n"
93+"At the end of the main menu you will find two options. One is\n"
94+"for saving the current configuration to a file of your choosing.\n"
95+"The other option is for loading a previously saved alternate\n"
96+"configuration.\n"
97+"\n"
98+"Even if you don't use alternate configuration files, but you\n"
99+"find during a nconfig session that you have completely messed\n"
100+"up your settings, you may use the \"Load Alternate...\" option to\n"
101+"restore your previously saved settings from \".config\" without\n"
102+"restarting nconfig.\n"
103+"\n"
104+"Other information\n"
105+"-----------------\n"
106+"If you use nconfig in an XTERM window make sure you have your\n"
107+"$TERM variable set to point to a xterm definition which supports color.\n"
108+"Otherwise, nconfig will look rather bad. nconfig will not\n"
109+"display correctly in a RXVT window because rxvt displays only one\n"
110+"intensity of color, bright.\n"
111+"\n"
112+"nconfig will display larger menus on screens or xterms which are\n"
113+"set to display more than the standard 25 row by 80 column geometry.\n"
114+"In order for this to work, the \"stty size\" command must be able to\n"
115+"display the screen's current row and column geometry. I STRONGLY\n"
116+"RECOMMEND that you make sure you do NOT have the shell variables\n"
117+"LINES and COLUMNS exported into your environment. Some distributions\n"
118+"export those variables via /etc/profile. Some ncurses programs can\n"
119+"become confused when those variables (LINES & COLUMNS) don't reflect\n"
120+"the true screen size.\n"
121+"\n"
122+"Optional personality available\n"
123+"------------------------------\n"
124+"If you prefer to have all of the kernel options listed in a single\n"
125+"menu, rather than the default multimenu hierarchy, run the nconfig\n"
126+"with NCONFIG_MODE environment variable set to single_menu. Example:\n"
127+"\n"
128+"make NCONFIG_MODE=single_menu nconfig\n"
129+"\n"
130+"<Enter> will then unroll the appropriate category, or enfold it if it\n"
131+"is already unrolled.\n"
132+"\n"
133+"Note that this mode can eventually be a little more CPU expensive\n"
134+"(especially with a larger number of unrolled categories) than the\n"
135+"default mode.\n"
136+"\n"),
137+menu_no_f_instructions[] = N_(
138+" You do not have function keys support. Please follow the\n"
139+" following instructions:\n"
140+" Arrow keys navigate the menu.\n"
141+" <Enter> or <right-arrow> selects submenus --->.\n"
142+" Capital Letters are hotkeys.\n"
143+" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
144+" Pressing SpaceBar toggles between the above options\n"
145+" Press <Esc> or <left-arrow> to go back one menu, \n"
146+" <?> or <h> for Help, </> for Search.\n"
147+" <1> is interchangable with <F1>, <2> with <F2>, etc.\n"
148+" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
149+" <Esc> always leaves the current window\n"),
150+menu_instructions[] = N_(
151+" Arrow keys navigate the menu.\n"
152+" <Enter> or <right-arrow> selects submenus --->.\n"
153+" Capital Letters are hotkeys.\n"
154+" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
155+" Pressing SpaceBar toggles between the above options\n"
156+" Press <Esc>, <F3> or <left-arrow> to go back one menu, \n"
157+" <?>, <F1> or <h> for Help, </> for Search.\n"
158+" <1> is interchangable with <F1>, <2> with <F2>, etc.\n"
159+" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
160+" <Esc> always leaves the current window\n"),
161+radiolist_instructions[] = N_(
162+" Use the arrow keys to navigate this window or\n"
163+" press the hotkey of the item you wish to select\n"
164+" followed by the <SPACE BAR>.\n"
165+" Press <?>, <F1> or <h> for additional information about this option.\n"),
166+inputbox_instructions_int[] = N_(
167+"Please enter a decimal value.\n"
168+"Fractions will not be accepted.\n"
169+"Press <RETURN> to accept, <ESC> to cancel."),
170+inputbox_instructions_hex[] = N_(
171+"Please enter a hexadecimal value.\n"
172+"Press <RETURN> to accept, <ESC> to cancel."),
173+inputbox_instructions_string[] = N_(
174+"Please enter a string value.\n"
175+"Press <RETURN> to accept, <ESC> to cancel."),
176+setmod_text[] = N_(
177+"This feature depends on another which\n"
178+"has been configured as a module.\n"
179+"As a result, this feature will be built as a module."),
180+nohelp_text[] = N_(
181+"There is no help available for this kernel option.\n"),
182+load_config_text[] = N_(
183+"Enter the name of the configuration file you wish to load.\n"
184+"Accept the name shown to restore the configuration you\n"
185+"last retrieved. Leave blank to abort."),
186+load_config_help[] = N_(
187+"\n"
188+"For various reasons, one may wish to keep several different kernel\n"
189+"configurations available on a single machine.\n"
190+"\n"
191+"If you have saved a previous configuration in a file other than the\n"
192+"kernel's default, entering the name of the file here will allow you\n"
193+"to modify that configuration.\n"
194+"\n"
195+"If you are uncertain, then you have probably never used alternate\n"
196+"configuration files. You should therefor leave this blank to abort.\n"),
197+save_config_text[] = N_(
198+"Enter a filename to which this configuration should be saved\n"
199+"as an alternate. Leave blank to abort."),
200+save_config_help[] = N_(
201+"\n"
202+"For various reasons, one may wish to keep different kernel\n"
203+"configurations available on a single machine.\n"
204+"\n"
205+"Entering a file name here will allow you to later retrieve, modify\n"
206+"and use the current configuration as an alternate to whatever\n"
207+"configuration options you have selected at that time.\n"
208+"\n"
209+"If you are uncertain what all this means then you should probably\n"
210+"leave this blank.\n"),
211+search_help[] = N_(
212+"\n"
213+"Search for CONFIG_ symbols and display their relations.\n"
214+"Regular expressions are allowed.\n"
215+"Example: search for \"^FOO\"\n"
216+"Result:\n"
217+"-----------------------------------------------------------------\n"
218+"Symbol: FOO [ = m]\n"
219+"Prompt: Foo bus is used to drive the bar HW\n"
220+"Defined at drivers/pci/Kconfig:47\n"
221+"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
222+"Location:\n"
223+" -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n"
224+" -> PCI support (PCI [ = y])\n"
225+" -> PCI access mode (<choice> [ = y])\n"
226+"Selects: LIBCRC32\n"
227+"Selected by: BAR\n"
228+"-----------------------------------------------------------------\n"
229+"o The line 'Prompt:' shows the text used in the menu structure for\n"
230+" this CONFIG_ symbol\n"
231+"o The 'Defined at' line tell at what file / line number the symbol\n"
232+" is defined\n"
233+"o The 'Depends on:' line tell what symbols needs to be defined for\n"
234+" this symbol to be visible in the menu (selectable)\n"
235+"o The 'Location:' lines tell where in the menu structure this symbol\n"
236+" is located\n"
237+" A location followed by a [ = y] indicate that this is a selectable\n"
238+" menu item - and current value is displayed inside brackets.\n"
239+"o The 'Selects:' line tell what symbol will be automatically\n"
240+" selected if this symbol is selected (y or m)\n"
241+"o The 'Selected by' line tell what symbol has selected this symbol\n"
242+"\n"
243+"Only relevant lines are shown.\n"
244+"\n\n"
245+"Search examples:\n"
246+"Examples: USB = > find all CONFIG_ symbols containing USB\n"
247+" ^USB => find all CONFIG_ symbols starting with USB\n"
248+" USB$ => find all CONFIG_ symbols ending with USB\n"
249+"\n");
250+
251+struct mitem {
252+ char str[256];
253+ char tag;
254+ void *usrptr;
255+ int is_hot;
256+ int is_visible;
257+};
258+
259+#define MAX_MENU_ITEMS 4096
260+static int show_all_items;
261+static int indent;
262+static struct menu *current_menu;
263+static int child_count;
264+static int single_menu_mode;
265+/* the window in which all information appears */
266+static WINDOW *main_window;
267+/* the largest size of the menu window */
268+static int mwin_max_lines;
269+static int mwin_max_cols;
270+/* the window in which we show option buttons */
271+static MENU *curses_menu;
272+static ITEM *curses_menu_items[MAX_MENU_ITEMS];
273+static struct mitem k_menu_items[MAX_MENU_ITEMS];
274+static int items_num;
275+static int global_exit;
276+/* the currently selected button */
277+const char *current_instructions = menu_instructions;
278+/* this array is used to implement hot keys. it is updated in item_make and
279+ * resetted in clean_items. It would be better to use a hash, but lets keep it
280+ * simple... */
281+#define MAX_SAME_KEY MAX_MENU_ITEMS
282+struct {
283+ int count;
284+ int ptrs[MAX_MENU_ITEMS];
285+} hotkeys[1<<(sizeof(char)*8)];
286+
287+static void conf(struct menu *menu);
288+static void conf_choice(struct menu *menu);
289+static void conf_string(struct menu *menu);
290+static void conf_load(void);
291+static void conf_save(void);
292+static void show_help(struct menu *menu);
293+static int do_exit(void);
294+static void setup_windows(void);
295+
296+typedef void (*function_key_handler_t)(int *key, struct menu *menu);
297+static void handle_f1(int *key, struct menu *current_item);
298+static void handle_f2(int *key, struct menu *current_item);
299+static void handle_f3(int *key, struct menu *current_item);
300+static void handle_f4(int *key, struct menu *current_item);
301+static void handle_f5(int *key, struct menu *current_item);
302+static void handle_f6(int *key, struct menu *current_item);
303+static void handle_f7(int *key, struct menu *current_item);
304+static void handle_f8(int *key, struct menu *current_item);
305+
306+struct function_keys {
307+ const char *key_str;
308+ const char *func;
309+ function_key key;
310+ function_key_handler_t handler;
311+};
312+
313+static const int function_keys_num = 8;
314+struct function_keys function_keys[] = {
315+ {
316+ .key_str = "F1",
317+ .func = "Help",
318+ .key = F_HELP,
319+ .handler = handle_f1,
320+ },
321+ {
322+ .key_str = "F2",
323+ .func = "Symbol Info",
324+ .key = F_SYMBOL,
325+ .handler = handle_f2,
326+ },
327+ {
328+ .key_str = "F3",
329+ .func = "Instructions",
330+ .key = F_INSTS,
331+ .handler = handle_f3,
332+ },
333+ {
334+ .key_str = "F4",
335+ .func = "Config",
336+ .key = F_CONF,
337+ .handler = handle_f4,
338+ },
339+ {
340+ .key_str = "F5",
341+ .func = "Back",
342+ .key = F_BACK,
343+ .handler = handle_f5,
344+ },
345+ {
346+ .key_str = "F6",
347+ .func = "Save",
348+ .key = F_SAVE,
349+ .handler = handle_f6,
350+ },
351+ {
352+ .key_str = "F7",
353+ .func = "Load",
354+ .key = F_LOAD,
355+ .handler = handle_f7,
356+ },
357+ {
358+ .key_str = "F8",
359+ .func = "Exit",
360+ .key = F_EXIT,
361+ .handler = handle_f8,
362+ },
363+};
364+
365+static void print_function_line(void)
366+{
367+ int i;
368+ int offset = 1;
369+ const int skip = 1;
370+
371+ for (i = 0; i < function_keys_num; i++) {
372+ wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
373+ mvwprintw(main_window, LINES-3, offset,
374+ "%s",
375+ function_keys[i].key_str);
376+ wattrset(main_window, attributes[FUNCTION_TEXT]);
377+ offset += strlen(function_keys[i].key_str);
378+ mvwprintw(main_window, LINES-3,
379+ offset, "%s",
380+ function_keys[i].func);
381+ offset += strlen(function_keys[i].func) + skip;
382+ }
383+ wattrset(main_window, attributes[NORMAL]);
384+}
385+
386+/* help */
387+static void handle_f1(int *key, struct menu *current_item)
388+{
389+ show_scroll_win(main_window,
390+ _("README"), _(nconf_readme));
391+ return;
392+}
393+
394+/* symbole help */
395+static void handle_f2(int *key, struct menu *current_item)
396+{
397+ show_help(current_item);
398+ return;
399+}
400+
401+/* instructions */
402+static void handle_f3(int *key, struct menu *current_item)
403+{
404+ show_scroll_win(main_window,
405+ _("Instructions"),
406+ _(current_instructions));
407+ return;
408+}
409+
410+/* config */
411+static void handle_f4(int *key, struct menu *current_item)
412+{
413+ int res = btn_dialog(main_window,
414+ _("Show all symbols?"),
415+ 2,
416+ " <Show All> ",
417+ "<Don't show all>");
418+ if (res == 0)
419+ show_all_items = 1;
420+ else if (res == 1)
421+ show_all_items = 0;
422+
423+ return;
424+}
425+
426+/* back */
427+static void handle_f5(int *key, struct menu *current_item)
428+{
429+ *key = KEY_LEFT;
430+ return;
431+}
432+
433+/* save */
434+static void handle_f6(int *key, struct menu *current_item)
435+{
436+ conf_save();
437+ return;
438+}
439+
440+/* load */
441+static void handle_f7(int *key, struct menu *current_item)
442+{
443+ conf_load();
444+ return;
445+}
446+
447+/* exit */
448+static void handle_f8(int *key, struct menu *current_item)
449+{
450+ do_exit();
451+ return;
452+}
453+
454+/* return != 0 to indicate the key was handles */
455+static int process_special_keys(int *key, struct menu *menu)
456+{
457+ int i;
458+
459+ if (*key == KEY_RESIZE) {
460+ setup_windows();
461+ return 1;
462+ }
463+
464+ for (i = 0; i < function_keys_num; i++) {
465+ if (*key == KEY_F(function_keys[i].key) ||
466+ *key == '0' + function_keys[i].key){
467+ function_keys[i].handler(key, menu);
468+ return 1;
469+ }
470+ }
471+
472+ return 0;
473+}
474+
475+static void clean_items(void)
476+{
477+ int i;
478+ for (i = 0; curses_menu_items[i]; i++)
479+ free_item(curses_menu_items[i]);
480+ bzero(curses_menu_items, sizeof(curses_menu_items));
481+ bzero(k_menu_items, sizeof(k_menu_items));
482+ bzero(hotkeys, sizeof(hotkeys));
483+ items_num = 0;
484+}
485+
486+/* return the index of the next hot item, or -1 if no such item exists */
487+static int get_next_hot(int c)
488+{
489+ static int hot_index;
490+ static int hot_char;
491+
492+ if (c < 0 || c > 255 || hotkeys[c].count <= 0)
493+ return -1;
494+
495+ if (hot_char == c) {
496+ hot_index = (hot_index+1)%hotkeys[c].count;
497+ return hotkeys[c].ptrs[hot_index];
498+ } else {
499+ hot_char = c;
500+ hot_index = 0;
501+ return hotkeys[c].ptrs[0];
502+ }
503+}
504+
505+/* can the char c be a hot key? no, if c is a common shortcut used elsewhere */
506+static int canbhot(char c)
507+{
508+ c = tolower(c);
509+ return isalnum(c) && c != 'y' && c != 'm' && c != 'h' &&
510+ c != 'n' && c != '?';
511+}
512+
513+/* check if str already contains a hot key. */
514+static int is_hot(int index)
515+{
516+ return k_menu_items[index].is_hot;
517+}
518+
519+/* find the first possible hot key, and mark it.
520+ * index is the index of the item in the menu
521+ * return 0 on success*/
522+static int make_hot(char *dest, int len, const char *org, int index)
523+{
524+ int position = -1;
525+ int i;
526+ int tmp;
527+ int c;
528+ int org_len = strlen(org);
529+
530+ if (org == NULL || is_hot(index))
531+ return 1;
532+
533+ /* make sure not to make hot keys out of markers.
534+ * find where to start looking for a hot key
535+ */
536+ i = 0;
537+ /* skip white space */
538+ while (i < org_len && org[i] == ' ')
539+ i++;
540+ if (i == org_len)
541+ return -1;
542+ /* if encountering '(' or '<' or '[', find the match and look from there
543+ **/
544+ if (org[i] == '[' || org[i] == '<' || org[i] == '(') {
545+ i++;
546+ for (; i < org_len; i++)
547+ if (org[i] == ']' || org[i] == '>' || org[i] == ')')
548+ break;
549+ }
550+ if (i == org_len)
551+ return -1;
552+ for (; i < org_len; i++) {
553+ if (canbhot(org[i]) && org[i-1] != '<' && org[i-1] != '(') {
554+ position = i;
555+ break;
556+ }
557+ }
558+ if (position == -1)
559+ return 1;
560+
561+ /* ok, char at org[position] should be a hot key to this item */
562+ c = tolower(org[position]);
563+ tmp = hotkeys[c].count;
564+ hotkeys[c].ptrs[tmp] = index;
565+ hotkeys[c].count++;
566+ /*
567+ snprintf(dest, len, "%.*s(%c)%s", position, org, org[position],
568+ &org[position+1]);
569+ */
570+ /* make org[position] uppercase, and all leading letter small case */
571+ strncpy(dest, org, len);
572+ for (i = 0; i < position; i++)
573+ dest[i] = tolower(dest[i]);
574+ dest[position] = toupper(dest[position]);
575+ k_menu_items[index].is_hot = 1;
576+ return 0;
577+}
578+
579+/* Make a new item. Add a hotkey mark in the first possible letter.
580+ * As ncurses does not allow any attributes inside menue item, we mark the
581+ * hot key as the first capitalized letter in the string */
582+static void item_make(struct menu *menu, char tag, const char *fmt, ...)
583+{
584+ va_list ap;
585+ char tmp_str[256];
586+
587+ if (items_num > MAX_MENU_ITEMS-1)
588+ return;
589+
590+ bzero(&k_menu_items[items_num], sizeof(k_menu_items[0]));
591+ k_menu_items[items_num].tag = tag;
592+ k_menu_items[items_num].usrptr = menu;
593+ if (menu != NULL)
594+ k_menu_items[items_num].is_visible =
595+ menu_is_visible(menu);
596+ else
597+ k_menu_items[items_num].is_visible = 1;
598+
599+ va_start(ap, fmt);
600+ vsnprintf(tmp_str, sizeof(tmp_str), fmt, ap);
601+ if (!k_menu_items[items_num].is_visible)
602+ memcpy(tmp_str, "XXX", 3);
603+ va_end(ap);
604+ if (make_hot(
605+ k_menu_items[items_num].str,
606+ sizeof(k_menu_items[items_num].str), tmp_str, items_num) != 0)
607+ strncpy(k_menu_items[items_num].str,
608+ tmp_str,
609+ sizeof(k_menu_items[items_num].str));
610+
611+ curses_menu_items[items_num] = new_item(
612+ k_menu_items[items_num].str,
613+ k_menu_items[items_num].str);
614+ set_item_userptr(curses_menu_items[items_num],
615+ &k_menu_items[items_num]);
616+ /*
617+ if (!k_menu_items[items_num].is_visible)
618+ item_opts_off(curses_menu_items[items_num], O_SELECTABLE);
619+ */
620+
621+ items_num++;
622+ curses_menu_items[items_num] = NULL;
623+}
624+
625+/* very hackish. adds a string to the last item added */
626+static void item_add_str(const char *fmt, ...)
627+{
628+ va_list ap;
629+ int index = items_num-1;
630+ char new_str[256];
631+ char tmp_str[256];
632+
633+ if (index < 0)
634+ return;
635+
636+ va_start(ap, fmt);
637+ vsnprintf(new_str, sizeof(new_str), fmt, ap);
638+ va_end(ap);
639+ snprintf(tmp_str, sizeof(tmp_str), "%s%s",
640+ k_menu_items[index].str, new_str);
641+ if (make_hot(k_menu_items[index].str,
642+ sizeof(k_menu_items[index].str), tmp_str, index) != 0)
643+ strncpy(k_menu_items[index].str,
644+ tmp_str,
645+ sizeof(k_menu_items[index].str));
646+
647+ free_item(curses_menu_items[index]);
648+ curses_menu_items[index] = new_item(
649+ k_menu_items[index].str,
650+ k_menu_items[index].str);
651+ set_item_userptr(curses_menu_items[index],
652+ &k_menu_items[index]);
653+}
654+
655+/* get the tag of the currently selected item */
656+static char item_tag(void)
657+{
658+ ITEM *cur;
659+ struct mitem *mcur;
660+
661+ cur = current_item(curses_menu);
662+ if (cur == NULL)
663+ return 0;
664+ mcur = (struct mitem *) item_userptr(cur);
665+ return mcur->tag;
666+}
667+
668+static int curses_item_index(void)
669+{
670+ return item_index(current_item(curses_menu));
671+}
672+
673+static void *item_data(void)
674+{
675+ ITEM *cur;
676+ struct mitem *mcur;
677+
678+ cur = current_item(curses_menu);
679+ mcur = (struct mitem *) item_userptr(cur);
680+ return mcur->usrptr;
681+
682+}
683+
684+static int item_is_tag(char tag)
685+{
686+ return item_tag() == tag;
687+}
688+
689+static char filename[PATH_MAX+1];
690+static char menu_backtitle[PATH_MAX+128];
691+static const char *set_config_filename(const char *config_filename)
692+{
693+ int size;
694+ struct symbol *sym;
695+
696+ sym = sym_lookup("KERNELVERSION", 0);
697+ sym_calc_value(sym);
698+ size = snprintf(menu_backtitle, sizeof(menu_backtitle),
699+ _("%s - Linux Kernel v%s Configuration"),
700+ config_filename, sym_get_string_value(sym));
701+ if (size >= sizeof(menu_backtitle))
702+ menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
703+
704+ size = snprintf(filename, sizeof(filename), "%s", config_filename);
705+ if (size >= sizeof(filename))
706+ filename[sizeof(filename)-1] = '\0';
707+ return menu_backtitle;
708+}
709+
710+/* command = 0 is supress, 1 is restore */
711+static void supress_stdout(int command)
712+{
713+ static FILE *org_stdout;
714+ static FILE *org_stderr;
715+
716+ if (command == 0) {
717+ org_stdout = stdout;
718+ org_stderr = stderr;
719+ stdout = fopen("/dev/null", "a");
720+ stderr = fopen("/dev/null", "a");
721+ } else {
722+ fclose(stdout);
723+ fclose(stderr);
724+ stdout = org_stdout;
725+ stderr = org_stderr;
726+ }
727+}
728+
729+/* return = 0 means we are successful.
730+ * -1 means go on doing what you were doing
731+ */
732+static int do_exit(void)
733+{
734+ int res;
735+ if (!conf_get_changed()) {
736+ global_exit = 1;
737+ return 0;
738+ }
739+ res = btn_dialog(main_window,
740+ _("Do you wish to save your "
741+ "new kernel configuration?\n"
742+ "<ESC> to cancel and resume nconfig."),
743+ 2,
744+ " <save> ",
745+ "<don't save>");
746+ if (res == KEY_EXIT) {
747+ global_exit = 0;
748+ return -1;
749+ }
750+
751+ /* if we got here, the user really wants to exit */
752+ switch (res) {
753+ case 0:
754+ supress_stdout(0);
755+ res = conf_write(filename);
756+ supress_stdout(1);
757+ if (res)
758+ btn_dialog(
759+ main_window,
760+ _("Error during writing of the kernel "
761+ "configuration.\n"
762+ "Your kernel configuration "
763+ "changes were NOT saved."),
764+ 1,
765+ "<OK>");
766+ else {
767+ char buf[1024];
768+ snprintf(buf, 1024,
769+ _("Configuration written to %s\n"
770+ "End of Linux kernel configuration.\n"
771+ "Execute 'make' to build the kernel or try"
772+ " 'make help'."), filename);
773+ btn_dialog(
774+ main_window,
775+ buf,
776+ 1,
777+ "<OK>");
778+ }
779+ break;
780+ default:
781+ btn_dialog(
782+ main_window,
783+ _("Your kernel configuration changes were NOT saved."),
784+ 1,
785+ "<OK>");
786+ break;
787+ }
788+ global_exit = 1;
789+ return 0;
790+}
791+
792+
793+static void search_conf(void)
794+{
795+ struct symbol **sym_arr;
796+ struct gstr res;
797+ char dialog_input_result[100];
798+ char *dialog_input;
799+ int dres;
800+again:
801+ dres = dialog_inputbox(main_window,
802+ _("Search Configuration Parameter"),
803+ _("Enter CONFIG_ (sub)string to search for "
804+ "(with or without \"CONFIG\")"),
805+ "", dialog_input_result, 99);
806+ switch (dres) {
807+ case 0:
808+ break;
809+ case 1:
810+ show_scroll_win(main_window,
811+ _("Search Configuration"), search_help);
812+ goto again;
813+ default:
814+ return;
815+ }
816+
817+ /* strip CONFIG_ if necessary */
818+ dialog_input = dialog_input_result;
819+ if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0)
820+ dialog_input += 7;
821+
822+ sym_arr = sym_re_search(dialog_input);
823+ res = get_relations_str(sym_arr);
824+ free(sym_arr);
825+ show_scroll_win(main_window,
826+ _("Search Results"), str_get(&res));
827+ str_free(&res);
828+}
829+
830+
831+static void build_conf(struct menu *menu)
832+{
833+ struct symbol *sym;
834+ struct property *prop;
835+ struct menu *child;
836+ int type, tmp, doint = 2;
837+ tristate val;
838+ char ch;
839+
840+ if (!menu || (!show_all_items && !menu_is_visible(menu)))
841+ return;
842+
843+ sym = menu->sym;
844+ prop = menu->prompt;
845+ if (!sym) {
846+ if (prop && menu != current_menu) {
847+ const char *prompt = menu_get_prompt(menu);
848+ enum prop_type ptype;
849+ ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
850+ switch (ptype) {
851+ case P_MENU:
852+ child_count++;
853+ prompt = _(prompt);
854+ if (single_menu_mode) {
855+ item_make(menu, 'm',
856+ "%s%*c%s",
857+ menu->data ? "-->" : "++>",
858+ indent + 1, ' ', prompt);
859+ } else
860+ item_make(menu, 'm',
861+ " %*c%s --->",
862+ indent + 1,
863+ ' ', prompt);
864+
865+ if (single_menu_mode && menu->data)
866+ goto conf_childs;
867+ return;
868+ case P_COMMENT:
869+ if (prompt) {
870+ child_count++;
871+ item_make(menu, ':',
872+ " %*c*** %s ***",
873+ indent + 1, ' ',
874+ _(prompt));
875+ }
876+ break;
877+ default:
878+ if (prompt) {
879+ child_count++;
880+ item_make(menu, ':', "---%*c%s",
881+ indent + 1, ' ',
882+ _(prompt));
883+ }
884+ }
885+ } else
886+ doint = 0;
887+ goto conf_childs;
888+ }
889+
890+ type = sym_get_type(sym);
891+ if (sym_is_choice(sym)) {
892+ struct symbol *def_sym = sym_get_choice_value(sym);
893+ struct menu *def_menu = NULL;
894+
895+ child_count++;
896+ for (child = menu->list; child; child = child->next) {
897+ if (menu_is_visible(child) && child->sym == def_sym)
898+ def_menu = child;
899+ }
900+
901+ val = sym_get_tristate_value(sym);
902+ if (sym_is_changable(sym)) {
903+ switch (type) {
904+ case S_BOOLEAN:
905+ item_make(menu, 't', "[%c]",
906+ val == no ? ' ' : '*');
907+ break;
908+ case S_TRISTATE:
909+ switch (val) {
910+ case yes:
911+ ch = '*';
912+ break;
913+ case mod:
914+ ch = 'M';
915+ break;
916+ default:
917+ ch = ' ';
918+ break;
919+ }
920+ item_make(menu, 't', "<%c>", ch);
921+ break;
922+ }
923+ } else {
924+ item_make(menu, def_menu ? 't' : ':', " ");
925+ }
926+
927+ item_add_str("%*c%s", indent + 1,
928+ ' ', _(menu_get_prompt(menu)));
929+ if (val == yes) {
930+ if (def_menu) {
931+ item_add_str(" (%s)",
932+ _(menu_get_prompt(def_menu)));
933+ item_add_str(" --->");
934+ if (def_menu->list) {
935+ indent += 2;
936+ build_conf(def_menu);
937+ indent -= 2;
938+ }
939+ }
940+ return;
941+ }
942+ } else {
943+ if (menu == current_menu) {
944+ item_make(menu, ':',
945+ "---%*c%s", indent + 1,
946+ ' ', _(menu_get_prompt(menu)));
947+ goto conf_childs;
948+ }
949+ child_count++;
950+ val = sym_get_tristate_value(sym);
951+ if (sym_is_choice_value(sym) && val == yes) {
952+ item_make(menu, ':', " ");
953+ } else {
954+ switch (type) {
955+ case S_BOOLEAN:
956+ if (sym_is_changable(sym))
957+ item_make(menu, 't', "[%c]",
958+ val == no ? ' ' : '*');
959+ else
960+ item_make(menu, 't', "-%c-",
961+ val == no ? ' ' : '*');
962+ break;
963+ case S_TRISTATE:
964+ switch (val) {
965+ case yes:
966+ ch = '*';
967+ break;
968+ case mod:
969+ ch = 'M';
970+ break;
971+ default:
972+ ch = ' ';
973+ break;
974+ }
975+ if (sym_is_changable(sym)) {
976+ if (sym->rev_dep.tri == mod)
977+ item_make(menu,
978+ 't', "{%c}", ch);
979+ else
980+ item_make(menu,
981+ 't', "<%c>", ch);
982+ } else
983+ item_make(menu, 't', "-%c-", ch);
984+ break;
985+ default:
986+ tmp = 2 + strlen(sym_get_string_value(sym));
987+ item_make(menu, 's', " (%s)",
988+ sym_get_string_value(sym));
989+ tmp = indent - tmp + 4;
990+ if (tmp < 0)
991+ tmp = 0;
992+ item_add_str("%*c%s%s", tmp, ' ',
993+ _(menu_get_prompt(menu)),
994+ (sym_has_value(sym) ||
995+ !sym_is_changable(sym)) ? "" :
996+ _(" (NEW)"));
997+ goto conf_childs;
998+ }
999+ }
1000+ item_add_str("%*c%s%s", indent + 1, ' ',
1001+ _(menu_get_prompt(menu)),
1002+ (sym_has_value(sym) || !sym_is_changable(sym)) ?
1003+ "" : _(" (NEW)"));
1004+ if (menu->prompt && menu->prompt->type == P_MENU) {
1005+ item_add_str(" --->");
1006+ return;
1007+ }
1008+ }
1009+
1010+conf_childs:
1011+ indent += doint;
1012+ for (child = menu->list; child; child = child->next)
1013+ build_conf(child);
1014+ indent -= doint;
1015+}
1016+
1017+static void reset_menu(void)
1018+{
1019+ unpost_menu(curses_menu);
1020+ clean_items();
1021+}
1022+
1023+/* adjust the menu to show this item.
1024+ * prefer not to scroll the menu if possible*/
1025+static void center_item(int selected_index, int *last_top_row)
1026+{
1027+ int toprow;
1028+ int maxy, maxx;
1029+
1030+ scale_menu(curses_menu, &maxy, &maxx);
1031+ set_top_row(curses_menu, *last_top_row);
1032+ toprow = top_row(curses_menu);
1033+ if (selected_index >= toprow && selected_index < toprow+maxy) {
1034+ /* we can only move the selected item. no need to scroll */
1035+ set_current_item(curses_menu,
1036+ curses_menu_items[selected_index]);
1037+ } else {
1038+ toprow = max(selected_index-maxy/2, 0);
1039+ if (toprow >= item_count(curses_menu)-maxy)
1040+ toprow = item_count(curses_menu)-mwin_max_lines;
1041+ set_top_row(curses_menu, toprow);
1042+ set_current_item(curses_menu,
1043+ curses_menu_items[selected_index]);
1044+ }
1045+ *last_top_row = toprow;
1046+ post_menu(curses_menu);
1047+ refresh_all_windows(main_window);
1048+}
1049+
1050+/* this function assumes reset_menu has been called before */
1051+static void show_menu(const char *prompt, const char *instructions,
1052+ int selected_index, int *last_top_row)
1053+{
1054+ int maxx, maxy;
1055+ WINDOW *menu_window;
1056+
1057+ current_instructions = instructions;
1058+
1059+ clear();
1060+ wattrset(main_window, attributes[NORMAL]);
1061+ print_in_middle(stdscr, 1, 0, COLS,
1062+ menu_backtitle,
1063+ attributes[MAIN_HEADING]);
1064+
1065+ wattrset(main_window, attributes[MAIN_MENU_BOX]);
1066+ box(main_window, 0, 0);
1067+ wattrset(main_window, attributes[MAIN_MENU_HEADING]);
1068+ mvwprintw(main_window, 0, 3, " %s ", prompt);
1069+ wattrset(main_window, attributes[NORMAL]);
1070+
1071+ set_menu_items(curses_menu, curses_menu_items);
1072+
1073+ /* position the menu at the middle of the screen */
1074+ scale_menu(curses_menu, &maxy, &maxx);
1075+ maxx = min(maxx, mwin_max_cols-2);
1076+ maxy = mwin_max_lines-2;
1077+ menu_window = derwin(main_window,
1078+ maxy,
1079+ maxx,
1080+ 2,
1081+ (mwin_max_cols-maxx)/2);
1082+ keypad(menu_window, TRUE);
1083+ set_menu_win(curses_menu, menu_window);
1084+ set_menu_sub(curses_menu, menu_window);
1085+
1086+ /* must reassert this after changing items, otherwise returns to a
1087+ * default of 16
1088+ */
1089+ set_menu_format(curses_menu, maxy, 1);
1090+ center_item(selected_index, last_top_row);
1091+ set_menu_format(curses_menu, maxy, 1);
1092+
1093+ print_function_line();
1094+
1095+ /* Post the menu */
1096+ post_menu(curses_menu);
1097+ refresh_all_windows(main_window);
1098+}
1099+
1100+
1101+static void conf(struct menu *menu)
1102+{
1103+ char pattern[256];
1104+ struct menu *submenu = 0;
1105+ const char *prompt = menu_get_prompt(menu);
1106+ struct symbol *sym;
1107+ struct menu *active_menu = NULL;
1108+ int res;
1109+ int current_index = 0;
1110+ int last_top_row = 0;
1111+
1112+ bzero(pattern, sizeof(pattern));
1113+
1114+ while (!global_exit) {
1115+ reset_menu();
1116+ current_menu = menu;
1117+ build_conf(menu);
1118+ if (!child_count)
1119+ break;
1120+
1121+ show_menu(prompt ? _(prompt) : _("Main Menu"),
1122+ _(menu_instructions),
1123+ current_index, &last_top_row);
1124+ keypad((menu_win(curses_menu)), TRUE);
1125+ while (!global_exit && (res = wgetch(menu_win(curses_menu)))) {
1126+ if (process_special_keys(&res,
1127+ (struct menu *) item_data()))
1128+ break;
1129+ switch (res) {
1130+ case KEY_DOWN:
1131+ menu_driver(curses_menu, REQ_DOWN_ITEM);
1132+ break;
1133+ case KEY_UP:
1134+ menu_driver(curses_menu, REQ_UP_ITEM);
1135+ break;
1136+ case KEY_NPAGE:
1137+ menu_driver(curses_menu, REQ_SCR_DPAGE);
1138+ break;
1139+ case KEY_PPAGE:
1140+ menu_driver(curses_menu, REQ_SCR_UPAGE);
1141+ break;
1142+ case KEY_HOME:
1143+ menu_driver(curses_menu, REQ_FIRST_ITEM);
1144+ break;
1145+ case KEY_END:
1146+ menu_driver(curses_menu, REQ_LAST_ITEM);
1147+ break;
1148+ case 'h':
1149+ case '?':
1150+ show_help((struct menu *) item_data());
1151+ break;
1152+ }
1153+ if (res == 10 || res == 27 ||
1154+ res == 32 || res == 'n' || res == 'y' ||
1155+ res == KEY_LEFT || res == KEY_RIGHT ||
1156+ res == 'm' || res == '/')
1157+ break;
1158+ else if (canbhot(res)) {
1159+ /* check for hot keys: */
1160+ int tmp = get_next_hot(res);
1161+ if (tmp != -1)
1162+ center_item(tmp, &last_top_row);
1163+ }
1164+ refresh_all_windows(main_window);
1165+ }
1166+
1167+ refresh_all_windows(main_window);
1168+ /* if ESC or left*/
1169+ if (res == 27 || (menu != &rootmenu && res == KEY_LEFT))
1170+ break;
1171+
1172+ /* remember location in the menu */
1173+ last_top_row = top_row(curses_menu);
1174+ current_index = curses_item_index();
1175+
1176+ if (!item_tag())
1177+ continue;
1178+
1179+ submenu = (struct menu *) item_data();
1180+ active_menu = (struct menu *)item_data();
1181+ if (!submenu || !menu_is_visible(submenu))
1182+ continue;
1183+ if (submenu)
1184+ sym = submenu->sym;
1185+ else
1186+ sym = NULL;
1187+
1188+ switch (res) {
1189+ case ' ':
1190+ if (item_is_tag('t'))
1191+ sym_toggle_tristate_value(sym);
1192+ else if (item_is_tag('m'))
1193+ conf(submenu);
1194+ break;
1195+ case KEY_RIGHT:
1196+ case 10: /* ENTER WAS PRESSED */
1197+ switch (item_tag()) {
1198+ case 'm':
1199+ if (single_menu_mode)
1200+ submenu->data =
1201+ (void *) (long) !submenu->data;
1202+ else
1203+ conf(submenu);
1204+ break;
1205+ case 't':
1206+ if (sym_is_choice(sym) &&
1207+ sym_get_tristate_value(sym) == yes)
1208+ conf_choice(submenu);
1209+ else if (submenu->prompt &&
1210+ submenu->prompt->type == P_MENU)
1211+ conf(submenu);
1212+ else if (res == 10)
1213+ sym_toggle_tristate_value(sym);
1214+ break;
1215+ case 's':
1216+ conf_string(submenu);
1217+ break;
1218+ }
1219+ break;
1220+ case 'y':
1221+ if (item_is_tag('t')) {
1222+ if (sym_set_tristate_value(sym, yes))
1223+ break;
1224+ if (sym_set_tristate_value(sym, mod))
1225+ btn_dialog(main_window, setmod_text, 0);
1226+ }
1227+ break;
1228+ case 'n':
1229+ if (item_is_tag('t'))
1230+ sym_set_tristate_value(sym, no);
1231+ break;
1232+ case 'm':
1233+ if (item_is_tag('t'))
1234+ sym_set_tristate_value(sym, mod);
1235+ break;
1236+ case '/':
1237+ search_conf();
1238+ break;
1239+ }
1240+ }
1241+}
1242+
1243+static void show_help(struct menu *menu)
1244+{
1245+ struct gstr help = str_new();
1246+
1247+ if (menu && menu->sym && menu_has_help(menu)) {
1248+ if (menu->sym->name) {
1249+ str_printf(&help, "CONFIG_%s:\n\n", menu->sym->name);
1250+ str_append(&help, _(menu_get_help(menu)));
1251+ str_append(&help, "\n");
1252+ get_symbol_str(&help, menu->sym);
1253+ }
1254+ } else {
1255+ str_append(&help, nohelp_text);
1256+ }
1257+ show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help));
1258+ str_free(&help);
1259+}
1260+
1261+static void conf_choice(struct menu *menu)
1262+{
1263+ const char *prompt = _(menu_get_prompt(menu));
1264+ struct menu *child = 0;
1265+ struct symbol *active;
1266+ int selected_index = 0;
1267+ int last_top_row = 0;
1268+ int res, i = 0;
1269+
1270+ active = sym_get_choice_value(menu->sym);
1271+ /* this is mostly duplicated from the conf() function. */
1272+ while (!global_exit) {
1273+ reset_menu();
1274+
1275+ for (i = 0, child = menu->list; child; child = child->next) {
1276+ if (!show_all_items && !menu_is_visible(child))
1277+ continue;
1278+
1279+ if (child->sym == sym_get_choice_value(menu->sym))
1280+ item_make(child, ':', "<X> %s",
1281+ _(menu_get_prompt(child)));
1282+ else
1283+ item_make(child, ':', " %s",
1284+ _(menu_get_prompt(child)));
1285+ if (child->sym == active){
1286+ last_top_row = top_row(curses_menu);
1287+ selected_index = i;
1288+ }
1289+ i++;
1290+ }
1291+ show_menu(prompt ? _(prompt) : _("Choice Menu"),
1292+ _(radiolist_instructions),
1293+ selected_index,
1294+ &last_top_row);
1295+ while (!global_exit && (res = wgetch(menu_win(curses_menu)))) {
1296+ if (process_special_keys(
1297+ &res,
1298+ (struct menu *) item_data()))
1299+ break;
1300+ switch (res) {
1301+ case KEY_DOWN:
1302+ menu_driver(curses_menu, REQ_DOWN_ITEM);
1303+ break;
1304+ case KEY_UP:
1305+ menu_driver(curses_menu, REQ_UP_ITEM);
1306+ break;
1307+ case KEY_NPAGE:
1308+ menu_driver(curses_menu, REQ_SCR_DPAGE);
1309+ break;
1310+ case KEY_PPAGE:
1311+ menu_driver(curses_menu, REQ_SCR_UPAGE);
1312+ break;
1313+ case KEY_HOME:
1314+ menu_driver(curses_menu, REQ_FIRST_ITEM);
1315+ break;
1316+ case KEY_END:
1317+ menu_driver(curses_menu, REQ_LAST_ITEM);
1318+ break;
1319+ case 'h':
1320+ case '?':
1321+ show_help((struct menu *) item_data());
1322+ break;
1323+ }
1324+ if (res == 10 || res == 27 || res == ' ' ||
1325+ res == KEY_LEFT)
1326+ break;
1327+ else if (canbhot(res)) {
1328+ /* check for hot keys: */
1329+ int tmp = get_next_hot(res);
1330+ if (tmp != -1)
1331+ center_item(tmp, &last_top_row);
1332+ }
1333+ refresh_all_windows(main_window);
1334+ }
1335+ /* if ESC or left */
1336+ if (res == 27 || res == KEY_LEFT)
1337+ break;
1338+
1339+ child = item_data();
1340+ if (!child || !menu_is_visible(child))
1341+ continue;
1342+ switch (res) {
1343+ case ' ':
1344+ case 10:
1345+ case KEY_RIGHT:
1346+ sym_set_tristate_value(child->sym, yes);
1347+ return;
1348+ case 'h':
1349+ case '?':
1350+ show_help(child);
1351+ active = child->sym;
1352+ break;
1353+ case KEY_EXIT:
1354+ return;
1355+ }
1356+ }
1357+}
1358+
1359+static void conf_string(struct menu *menu)
1360+{
1361+ const char *prompt = menu_get_prompt(menu);
1362+ char dialog_input_result[256];
1363+
1364+ while (1) {
1365+ int res;
1366+ const char *heading;
1367+
1368+ switch (sym_get_type(menu->sym)) {
1369+ case S_INT:
1370+ heading = _(inputbox_instructions_int);
1371+ break;
1372+ case S_HEX:
1373+ heading = _(inputbox_instructions_hex);
1374+ break;
1375+ case S_STRING:
1376+ heading = _(inputbox_instructions_string);
1377+ break;
1378+ default:
1379+ heading = _("Internal nconf error!");
1380+ }
1381+ res = dialog_inputbox(main_window,
1382+ prompt ? _(prompt) : _("Main Menu"),
1383+ heading,
1384+ sym_get_string_value(menu->sym),
1385+ dialog_input_result,
1386+ sizeof(dialog_input_result));
1387+ switch (res) {
1388+ case 0:
1389+ if (sym_set_string_value(menu->sym,
1390+ dialog_input_result))
1391+ return;
1392+ btn_dialog(main_window,
1393+ _("You have made an invalid entry."), 0);
1394+ break;
1395+ case 1:
1396+ show_help(menu);
1397+ break;
1398+ case KEY_EXIT:
1399+ return;
1400+ }
1401+ }
1402+}
1403+
1404+static void conf_load(void)
1405+{
1406+ char dialog_input_result[256];
1407+ while (1) {
1408+ int res;
1409+ res = dialog_inputbox(main_window,
1410+ NULL, load_config_text,
1411+ filename,
1412+ dialog_input_result,
1413+ sizeof(dialog_input_result));
1414+ switch (res) {
1415+ case 0:
1416+ if (!dialog_input_result[0])
1417+ return;
1418+ if (!conf_read(dialog_input_result)) {
1419+ set_config_filename(dialog_input_result);
1420+ sym_set_change_count(1);
1421+ return;
1422+ }
1423+ btn_dialog(main_window, _("File does not exist!"), 0);
1424+ break;
1425+ case 1:
1426+ show_scroll_win(main_window,
1427+ _("Load Alternate Configuration"),
1428+ load_config_help);
1429+ break;
1430+ case KEY_EXIT:
1431+ return;
1432+ }
1433+ }
1434+}
1435+
1436+static void conf_save(void)
1437+{
1438+ char dialog_input_result[256];
1439+ while (1) {
1440+ int res;
1441+ res = dialog_inputbox(main_window,
1442+ NULL, save_config_text,
1443+ filename,
1444+ dialog_input_result,
1445+ sizeof(dialog_input_result));
1446+ switch (res) {
1447+ case 0:
1448+ if (!dialog_input_result[0])
1449+ return;
1450+ supress_stdout(0);
1451+ res = conf_write(dialog_input_result);
1452+ supress_stdout(1);
1453+ if (!res) {
1454+ char buf[1024];
1455+ sprintf(buf, "%s %s",
1456+ _("configuration file saved to: "),
1457+ dialog_input_result);
1458+ btn_dialog(main_window,
1459+ buf, 1, "<OK>");
1460+ set_config_filename(dialog_input_result);
1461+ return;
1462+ }
1463+ btn_dialog(main_window, _("Can't create file! "
1464+ "Probably a nonexistent directory."),
1465+ 1, "<OK>");
1466+ break;
1467+ case 1:
1468+ show_scroll_win(main_window,
1469+ _("Save Alternate Configuration"),
1470+ save_config_help);
1471+ break;
1472+ case KEY_EXIT:
1473+ return;
1474+ }
1475+ }
1476+}
1477+
1478+void setup_windows(void)
1479+{
1480+ if (main_window != NULL)
1481+ delwin(main_window);
1482+
1483+ /* set up the menu and menu window */
1484+ main_window = newwin(LINES-2, COLS-2, 2, 1);
1485+ keypad(main_window, TRUE);
1486+ mwin_max_lines = LINES-6;
1487+ mwin_max_cols = COLS-6;
1488+
1489+ /* panels order is from bottom to top */
1490+ new_panel(main_window);
1491+}
1492+
1493+int main(int ac, char **av)
1494+{
1495+ char *mode;
1496+
1497+ setlocale(LC_ALL, "");
1498+ bindtextdomain(PACKAGE, LOCALEDIR);
1499+ textdomain(PACKAGE);
1500+
1501+ conf_parse(av[1]);
1502+ conf_read(NULL);
1503+
1504+ mode = getenv("NCONFIG_MODE");
1505+ if (mode) {
1506+ if (!strcasecmp(mode, "single_menu"))
1507+ single_menu_mode = 1;
1508+ }
1509+
1510+ /* Initialize curses */
1511+ initscr();
1512+ /* set color theme */
1513+ set_colors();
1514+
1515+ cbreak();
1516+ noecho();
1517+ keypad(stdscr, TRUE);
1518+ curs_set(0);
1519+
1520+ if (COLS < 75 || LINES < 20) {
1521+ endwin();
1522+ printf("Your terminal should have at "
1523+ "least 20 lines and 75 columns\n");
1524+ return 1;
1525+ }
1526+
1527+ notimeout(stdscr, FALSE);
1528+ ESCDELAY = 1;
1529+
1530+ /* set btns menu */
1531+ curses_menu = new_menu(curses_menu_items);
1532+ menu_opts_off(curses_menu, O_SHOWDESC);
1533+ menu_opts_off(curses_menu, O_SHOWMATCH);
1534+ menu_opts_on(curses_menu, O_ONEVALUE);
1535+ menu_opts_on(curses_menu, O_NONCYCLIC);
1536+ set_menu_mark(curses_menu, " ");
1537+ set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]);
1538+ set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]);
1539+ set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]);
1540+
1541+ set_config_filename(conf_get_configname());
1542+ setup_windows();
1543+
1544+ /* check for KEY_FUNC(1) */
1545+ if (has_key(KEY_F(1)) == FALSE) {
1546+ show_scroll_win(main_window,
1547+ _("Instructions"),
1548+ _(menu_no_f_instructions));
1549+ }
1550+
1551+
1552+
1553+ /* do the work */
1554+ while (!global_exit) {
1555+ conf(&rootmenu);
1556+ if (!global_exit && do_exit() == 0)
1557+ break;
1558+ }
1559+ /* ok, we are done */
1560+ unpost_menu(curses_menu);
1561+ free_menu(curses_menu);
1562+ delwin(main_window);
1563+ clear();
1564+ refresh();
1565+ endwin();
1566+ return 0;
1567+}
1568+
scripts/kconfig/nconf.gui.c+617−0
@@ -0,0 +1,617 @@
1+/*
2+ * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
3+ * Released under the terms of the GNU GPL v2.0.
4+ *
5+ * Derived from menuconfig.
6+ *
7+ */
8+#include "nconf.h"
9+
10+/* a list of all the different widgets we use */
11+attributes_t attributes[ATTR_MAX+1] = {0};
12+
13+/* available colors:
14+ COLOR_BLACK 0
15+ COLOR_RED 1
16+ COLOR_GREEN 2
17+ COLOR_YELLOW 3
18+ COLOR_BLUE 4
19+ COLOR_MAGENTA 5
20+ COLOR_CYAN 6
21+ COLOR_WHITE 7
22+ */
23+static void set_normal_colors(void)
24+{
25+ init_pair(NORMAL, -1, -1);
26+ init_pair(MAIN_HEADING, COLOR_MAGENTA, -1);
27+
28+ /* FORE is for the selected item */
29+ init_pair(MAIN_MENU_FORE, -1, -1);
30+ /* BACK for all the rest */
31+ init_pair(MAIN_MENU_BACK, -1, -1);
32+ init_pair(MAIN_MENU_GREY, -1, -1);
33+ init_pair(MAIN_MENU_HEADING, COLOR_GREEN, -1);
34+ init_pair(MAIN_MENU_BOX, COLOR_YELLOW, -1);
35+
36+ init_pair(SCROLLWIN_TEXT, -1, -1);
37+ init_pair(SCROLLWIN_HEADING, COLOR_GREEN, -1);
38+ init_pair(SCROLLWIN_BOX, COLOR_YELLOW, -1);
39+
40+ init_pair(DIALOG_TEXT, -1, -1);
41+ init_pair(DIALOG_BOX, COLOR_YELLOW, -1);
42+ init_pair(DIALOG_MENU_BACK, COLOR_YELLOW, -1);
43+ init_pair(DIALOG_MENU_FORE, COLOR_RED, -1);
44+
45+ init_pair(INPUT_BOX, COLOR_YELLOW, -1);
46+ init_pair(INPUT_HEADING, COLOR_GREEN, -1);
47+ init_pair(INPUT_TEXT, -1, -1);
48+ init_pair(INPUT_FIELD, -1, -1);
49+
50+ init_pair(FUNCTION_HIGHLIGHT, -1, -1);
51+ init_pair(FUNCTION_TEXT, COLOR_BLUE, -1);
52+}
53+
54+/* available attributes:
55+ A_NORMAL Normal display (no highlight)
56+ A_STANDOUT Best highlighting mode of the terminal.
57+ A_UNDERLINE Underlining
58+ A_REVERSE Reverse video
59+ A_BLINK Blinking
60+ A_DIM Half bright
61+ A_BOLD Extra bright or bold
62+ A_PROTECT Protected mode
63+ A_INVIS Invisible or blank mode
64+ A_ALTCHARSET Alternate character set
65+ A_CHARTEXT Bit-mask to extract a character
66+ COLOR_PAIR(n) Color-pair number n
67+ */
68+static void normal_color_theme(void)
69+{
70+ /* automatically add color... */
71+#define mkattr(name, attr) do { \
72+attributes[name] = attr | COLOR_PAIR(name); } while (0)
73+ mkattr(NORMAL, NORMAL);
74+ mkattr(MAIN_HEADING, A_BOLD | A_UNDERLINE);
75+
76+ mkattr(MAIN_MENU_FORE, A_REVERSE);
77+ mkattr(MAIN_MENU_BACK, A_NORMAL);
78+ mkattr(MAIN_MENU_GREY, A_NORMAL);
79+ mkattr(MAIN_MENU_HEADING, A_BOLD);
80+ mkattr(MAIN_MENU_BOX, A_NORMAL);
81+
82+ mkattr(SCROLLWIN_TEXT, A_NORMAL);
83+ mkattr(SCROLLWIN_HEADING, A_BOLD);
84+ mkattr(SCROLLWIN_BOX, A_BOLD);
85+
86+ mkattr(DIALOG_TEXT, A_BOLD);
87+ mkattr(DIALOG_BOX, A_BOLD);
88+ mkattr(DIALOG_MENU_FORE, A_STANDOUT);
89+ mkattr(DIALOG_MENU_BACK, A_NORMAL);
90+
91+ mkattr(INPUT_BOX, A_NORMAL);
92+ mkattr(INPUT_HEADING, A_BOLD);
93+ mkattr(INPUT_TEXT, A_NORMAL);
94+ mkattr(INPUT_FIELD, A_UNDERLINE);
95+
96+ mkattr(FUNCTION_HIGHLIGHT, A_BOLD);
97+ mkattr(FUNCTION_TEXT, A_REVERSE);
98+}
99+
100+static void no_colors_theme(void)
101+{
102+ /* automatically add highlight, no color */
103+#define mkattrn(name, attr) { attributes[name] = attr; }
104+
105+ mkattrn(NORMAL, NORMAL);
106+ mkattrn(MAIN_HEADING, A_BOLD | A_UNDERLINE);
107+
108+ mkattrn(MAIN_MENU_FORE, A_STANDOUT);
109+ mkattrn(MAIN_MENU_BACK, A_NORMAL);
110+ mkattrn(MAIN_MENU_GREY, A_NORMAL);
111+ mkattrn(MAIN_MENU_HEADING, A_BOLD);
112+ mkattrn(MAIN_MENU_BOX, A_NORMAL);
113+
114+ mkattrn(SCROLLWIN_TEXT, A_NORMAL);
115+ mkattrn(SCROLLWIN_HEADING, A_BOLD);
116+ mkattrn(SCROLLWIN_BOX, A_BOLD);
117+
118+ mkattrn(DIALOG_TEXT, A_NORMAL);
119+ mkattrn(DIALOG_BOX, A_BOLD);
120+ mkattrn(DIALOG_MENU_FORE, A_STANDOUT);
121+ mkattrn(DIALOG_MENU_BACK, A_NORMAL);
122+
123+ mkattrn(INPUT_BOX, A_BOLD);
124+ mkattrn(INPUT_HEADING, A_BOLD);
125+ mkattrn(INPUT_TEXT, A_NORMAL);
126+ mkattrn(INPUT_FIELD, A_UNDERLINE);
127+
128+ mkattrn(FUNCTION_HIGHLIGHT, A_BOLD);
129+ mkattrn(FUNCTION_TEXT, A_REVERSE);
130+}
131+
132+void set_colors()
133+{
134+ start_color();
135+ use_default_colors();
136+ set_normal_colors();
137+ if (has_colors()) {
138+ normal_color_theme();
139+ } else {
140+ /* give deafults */
141+ no_colors_theme();
142+ }
143+}
144+
145+
146+/* this changes the windows attributes !!! */
147+void print_in_middle(WINDOW *win,
148+ int starty,
149+ int startx,
150+ int width,
151+ const char *string,
152+ chtype color)
153+{ int length, x, y;
154+ float temp;
155+
156+
157+ if (win == NULL)
158+ win = stdscr;
159+ getyx(win, y, x);
160+ if (startx != 0)
161+ x = startx;
162+ if (starty != 0)
163+ y = starty;
164+ if (width == 0)
165+ width = 80;
166+
167+ length = strlen(string);
168+ temp = (width - length) / 2;
169+ x = startx + (int)temp;
170+ wattrset(win, color);
171+ mvwprintw(win, y, x, "%s", string);
172+ refresh();
173+}
174+
175+int get_line_no(const char *text)
176+{
177+ int i;
178+ int total = 1;
179+
180+ if (!text)
181+ return 0;
182+
183+ for (i = 0; text[i] != '\0'; i++)
184+ if (text[i] == '\n')
185+ total++;
186+ return total;
187+}
188+
189+const char *get_line(const char *text, int line_no)
190+{
191+ int i;
192+ int lines = 0;
193+
194+ if (!text)
195+ return 0;
196+
197+ for (i = 0; text[i] != '\0' && lines < line_no; i++)
198+ if (text[i] == '\n')
199+ lines++;
200+ return text+i;
201+}
202+
203+int get_line_length(const char *line)
204+{
205+ int res = 0;
206+ while (*line != '\0' && *line != '\n') {
207+ line++;
208+ res++;
209+ }
210+ return res;
211+}
212+
213+/* print all lines to the window. */
214+void fill_window(WINDOW *win, const char *text)
215+{
216+ int x, y;
217+ int total_lines = get_line_no(text);
218+ int i;
219+
220+ getmaxyx(win, y, x);
221+ /* do not go over end of line */
222+ total_lines = min(total_lines, y);
223+ for (i = 0; i < total_lines; i++) {
224+ char tmp[x+10];
225+ const char *line = get_line(text, i);
226+ int len = get_line_length(line);
227+ strncpy(tmp, line, min(len, x));
228+ tmp[len] = '\0';
229+ mvwprintw(win, i, 0, tmp);
230+ }
231+}
232+
233+/* get the message, and buttons.
234+ * each button must be a char*
235+ * return the selected button
236+ *
237+ * this dialog is used for 2 different things:
238+ * 1) show a text box, no buttons.
239+ * 2) show a dialog, with horizontal buttons
240+ */
241+int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
242+{
243+ va_list ap;
244+ char *btn;
245+ int btns_width = 0;
246+ int msg_lines = 0;
247+ int msg_width = 0;
248+ int total_width;
249+ int win_rows = 0;
250+ WINDOW *win;
251+ WINDOW *msg_win;
252+ WINDOW *menu_win;
253+ MENU *menu;
254+ ITEM *btns[btn_num+1];
255+ int i, x, y;
256+ int res = -1;
257+
258+
259+ va_start(ap, btn_num);
260+ for (i = 0; i < btn_num; i++) {
261+ btn = va_arg(ap, char *);
262+ btns[i] = new_item(btn, "");
263+ btns_width += strlen(btn)+1;
264+ }
265+ va_end(ap);
266+ btns[btn_num] = NULL;
267+
268+ /* find the widest line of msg: */
269+ msg_lines = get_line_no(msg);
270+ for (i = 0; i < msg_lines; i++) {
271+ const char *line = get_line(msg, i);
272+ int len = get_line_length(line);
273+ if (msg_width < len)
274+ msg_width = len;
275+ }
276+
277+ total_width = max(msg_width, btns_width);
278+ /* place dialog in middle of screen */
279+ y = (LINES-(msg_lines+4))/2;
280+ x = (COLS-(total_width+4))/2;
281+
282+
283+ /* create the windows */
284+ if (btn_num > 0)
285+ win_rows = msg_lines+4;
286+ else
287+ win_rows = msg_lines+2;
288+
289+ win = newwin(win_rows, total_width+4, y, x);
290+ keypad(win, TRUE);
291+ menu_win = derwin(win, 1, btns_width, win_rows-2,
292+ 1+(total_width+2-btns_width)/2);
293+ menu = new_menu(btns);
294+ msg_win = derwin(win, win_rows-2, msg_width, 1,
295+ 1+(total_width+2-msg_width)/2);
296+
297+ set_menu_fore(menu, attributes[DIALOG_MENU_FORE]);
298+ set_menu_back(menu, attributes[DIALOG_MENU_BACK]);
299+
300+ wattrset(win, attributes[DIALOG_BOX]);
301+ box(win, 0, 0);
302+
303+ /* print message */
304+ wattrset(msg_win, attributes[DIALOG_TEXT]);
305+ fill_window(msg_win, msg);
306+
307+ set_menu_win(menu, win);
308+ set_menu_sub(menu, menu_win);
309+ set_menu_format(menu, 1, btn_num);
310+ menu_opts_off(menu, O_SHOWDESC);
311+ menu_opts_off(menu, O_SHOWMATCH);
312+ menu_opts_on(menu, O_ONEVALUE);
313+ menu_opts_on(menu, O_NONCYCLIC);
314+ set_menu_mark(menu, "");
315+ post_menu(menu);
316+
317+
318+ touchwin(win);
319+ refresh_all_windows(main_window);
320+ while ((res = wgetch(win))) {
321+ switch (res) {
322+ case KEY_LEFT:
323+ menu_driver(menu, REQ_LEFT_ITEM);
324+ break;
325+ case KEY_RIGHT:
326+ menu_driver(menu, REQ_RIGHT_ITEM);
327+ break;
328+ case 10: /* ENTER */
329+ case 27: /* ESCAPE */
330+ case ' ':
331+ case KEY_F(F_BACK):
332+ case KEY_F(F_EXIT):
333+ break;
334+ }
335+ touchwin(win);
336+ refresh_all_windows(main_window);
337+
338+ if (res == 10 || res == ' ') {
339+ res = item_index(current_item(menu));
340+ break;
341+ } else if (res == 27 || res == KEY_F(F_BACK) ||
342+ res == KEY_F(F_EXIT)) {
343+ res = KEY_EXIT;
344+ break;
345+ }
346+ }
347+
348+ unpost_menu(menu);
349+ free_menu(menu);
350+ for (i = 0; i < btn_num; i++)
351+ free_item(btns[i]);
352+
353+ delwin(win);
354+ return res;
355+}
356+
357+int dialog_inputbox(WINDOW *main_window,
358+ const char *title, const char *prompt,
359+ const char *init, char *result, int result_len)
360+{
361+ int prompt_lines = 0;
362+ int prompt_width = 0;
363+ WINDOW *win;
364+ WINDOW *prompt_win;
365+ WINDOW *form_win;
366+ PANEL *panel;
367+ int i, x, y;
368+ int res = -1;
369+ int cursor_position = strlen(init);
370+
371+
372+ /* find the widest line of msg: */
373+ prompt_lines = get_line_no(prompt);
374+ for (i = 0; i < prompt_lines; i++) {
375+ const char *line = get_line(prompt, i);
376+ int len = get_line_length(line);
377+ prompt_width = max(prompt_width, len);
378+ }
379+
380+ if (title)
381+ prompt_width = max(prompt_width, strlen(title));
382+
383+ /* place dialog in middle of screen */
384+ y = (LINES-(prompt_lines+4))/2;
385+ x = (COLS-(prompt_width+4))/2;
386+
387+ strncpy(result, init, result_len);
388+
389+ /* create the windows */
390+ win = newwin(prompt_lines+6, prompt_width+7, y, x);
391+ prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2);
392+ form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2);
393+ keypad(form_win, TRUE);
394+
395+ wattrset(form_win, attributes[INPUT_FIELD]);
396+
397+ wattrset(win, attributes[INPUT_BOX]);
398+ box(win, 0, 0);
399+ wattrset(win, attributes[INPUT_HEADING]);
400+ if (title)
401+ mvwprintw(win, 0, 3, "%s", title);
402+
403+ /* print message */
404+ wattrset(prompt_win, attributes[INPUT_TEXT]);
405+ fill_window(prompt_win, prompt);
406+
407+ mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
408+ mvwprintw(form_win, 0, 0, "%s", result);
409+
410+ /* create panels */
411+ panel = new_panel(win);
412+
413+ /* show the cursor */
414+ curs_set(1);
415+
416+ touchwin(win);
417+ refresh_all_windows(main_window);
418+ while ((res = wgetch(form_win))) {
419+ int len = strlen(result);
420+ switch (res) {
421+ case 10: /* ENTER */
422+ case 27: /* ESCAPE */
423+ case KEY_F(F_HELP):
424+ case KEY_F(F_EXIT):
425+ case KEY_F(F_BACK):
426+ break;
427+ case 127:
428+ case KEY_BACKSPACE:
429+ if (cursor_position > 0) {
430+ memmove(&result[cursor_position-1],
431+ &result[cursor_position],
432+ len-cursor_position+1);
433+ cursor_position--;
434+ }
435+ break;
436+ case KEY_DC:
437+ if (cursor_position >= 0 && cursor_position < len) {
438+ memmove(&result[cursor_position],
439+ &result[cursor_position+1],
440+ len-cursor_position+1);
441+ }
442+ break;
443+ case KEY_UP:
444+ case KEY_RIGHT:
445+ if (cursor_position < len &&
446+ cursor_position < min(result_len, prompt_width))
447+ cursor_position++;
448+ break;
449+ case KEY_DOWN:
450+ case KEY_LEFT:
451+ if (cursor_position > 0)
452+ cursor_position--;
453+ break;
454+ default:
455+ if ((isgraph(res) || isspace(res)) &&
456+ len-2 < result_len) {
457+ /* insert the char at the proper position */
458+ memmove(&result[cursor_position+1],
459+ &result[cursor_position],
460+ len+1);
461+ result[cursor_position] = res;
462+ cursor_position++;
463+ } else {
464+ mvprintw(0, 0, "unknow key: %d\n", res);
465+ }
466+ break;
467+ }
468+ wmove(form_win, 0, 0);
469+ wclrtoeol(form_win);
470+ mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
471+ mvwprintw(form_win, 0, 0, "%s", result);
472+ wmove(form_win, 0, cursor_position);
473+ touchwin(win);
474+ refresh_all_windows(main_window);
475+
476+ if (res == 10) {
477+ res = 0;
478+ break;
479+ } else if (res == 27 || res == KEY_F(F_BACK) ||
480+ res == KEY_F(F_EXIT)) {
481+ res = KEY_EXIT;
482+ break;
483+ } else if (res == KEY_F(F_HELP)) {
484+ res = 1;
485+ break;
486+ }
487+ }
488+
489+ /* hide the cursor */
490+ curs_set(0);
491+ del_panel(panel);
492+ delwin(prompt_win);
493+ delwin(form_win);
494+ delwin(win);
495+ return res;
496+}
497+
498+/* refresh all windows in the correct order */
499+void refresh_all_windows(WINDOW *main_window)
500+{
501+ update_panels();
502+ touchwin(main_window);
503+ refresh();
504+}
505+
506+/* layman's scrollable window... */
507+void show_scroll_win(WINDOW *main_window,
508+ const char *title,
509+ const char *text)
510+{
511+ int res;
512+ int total_lines = get_line_no(text);
513+ int x, y;
514+ int start_x = 0, start_y = 0;
515+ int text_lines = 0, text_cols = 0;
516+ int total_cols = 0;
517+ int win_cols = 0;
518+ int win_lines = 0;
519+ int i = 0;
520+ WINDOW *win;
521+ WINDOW *pad;
522+ PANEL *panel;
523+
524+ /* find the widest line of msg: */
525+ total_lines = get_line_no(text);
526+ for (i = 0; i < total_lines; i++) {
527+ const char *line = get_line(text, i);
528+ int len = get_line_length(line);
529+ total_cols = max(total_cols, len+2);
530+ }
531+
532+ /* create the pad */
533+ pad = newpad(total_lines+10, total_cols+10);
534+ wattrset(pad, attributes[SCROLLWIN_TEXT]);
535+ fill_window(pad, text);
536+
537+ win_lines = min(total_lines+4, LINES-2);
538+ win_cols = min(total_cols+2, COLS-2);
539+ text_lines = max(win_lines-4, 0);
540+ text_cols = max(win_cols-2, 0);
541+
542+ /* place window in middle of screen */
543+ y = (LINES-win_lines)/2;
544+ x = (COLS-win_cols)/2;
545+
546+ win = newwin(win_lines, win_cols, y, x);
547+ keypad(win, TRUE);
548+ /* show the help in the help window, and show the help panel */
549+ wattrset(win, attributes[SCROLLWIN_BOX]);
550+ box(win, 0, 0);
551+ wattrset(win, attributes[SCROLLWIN_HEADING]);
552+ mvwprintw(win, 0, 3, " %s ", title);
553+ panel = new_panel(win);
554+
555+ /* handle scrolling */
556+ do {
557+
558+ copywin(pad, win, start_y, start_x, 2, 2, text_lines,
559+ text_cols, 0);
560+ print_in_middle(win,
561+ text_lines+2,
562+ 0,
563+ text_cols,
564+ "<OK>",
565+ attributes[DIALOG_MENU_FORE]);
566+ wrefresh(win);
567+
568+ res = wgetch(win);
569+ switch (res) {
570+ case KEY_NPAGE:
571+ case ' ':
572+ start_y += text_lines-2;
573+ break;
574+ case KEY_PPAGE:
575+ start_y -= text_lines+2;
576+ break;
577+ case KEY_HOME:
578+ start_y = 0;
579+ break;
580+ case KEY_END:
581+ start_y = total_lines-text_lines;
582+ break;
583+ case KEY_DOWN:
584+ case 'j':
585+ start_y++;
586+ break;
587+ case KEY_UP:
588+ case 'k':
589+ start_y--;
590+ break;
591+ case KEY_LEFT:
592+ case 'h':
593+ start_x--;
594+ break;
595+ case KEY_RIGHT:
596+ case 'l':
597+ start_x++;
598+ break;
599+ }
600+ if (res == 10 || res == 27 || res == 'q'
601+ || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) {
602+ break;
603+ }
604+ if (start_y < 0)
605+ start_y = 0;
606+ if (start_y >= total_lines-text_lines)
607+ start_y = total_lines-text_lines;
608+ if (start_x < 0)
609+ start_x = 0;
610+ if (start_x >= total_cols-text_cols)
611+ start_x = total_cols-text_cols;
612+ } while (res);
613+
614+ del_panel(panel);
615+ delwin(win);
616+ refresh_all_windows(main_window);
617+}
scripts/kconfig/nconf.h+95−0
@@ -0,0 +1,95 @@
1+/*
2+ * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
3+ * Released under the terms of the GNU GPL v2.0.
4+ *
5+ * Derived from menuconfig.
6+ *
7+ */
8+
9+#include <ctype.h>
10+#include <errno.h>
11+#include <fcntl.h>
12+#include <limits.h>
13+#include <stdarg.h>
14+#include <stdlib.h>
15+#include <string.h>
16+#include <unistd.h>
17+#include <locale.h>
18+#include <curses.h>
19+#include <menu.h>
20+#include <panel.h>
21+#include <form.h>
22+
23+#include <stdio.h>
24+#include <time.h>
25+#include <sys/time.h>
26+
27+#include "ncurses.h"
28+
29+#define max(a, b) ({\
30+ typeof(a) _a = a;\
31+ typeof(b) _b = b;\
32+ _a > _b ? _a : _b; })
33+
34+#define min(a, b) ({\
35+ typeof(a) _a = a;\
36+ typeof(b) _b = b;\
37+ _a < _b ? _a : _b; })
38+
39+typedef enum {
40+ NORMAL = 1,
41+ MAIN_HEADING,
42+ MAIN_MENU_BOX,
43+ MAIN_MENU_FORE,
44+ MAIN_MENU_BACK,
45+ MAIN_MENU_GREY,
46+ MAIN_MENU_HEADING,
47+ SCROLLWIN_TEXT,
48+ SCROLLWIN_HEADING,
49+ SCROLLWIN_BOX,
50+ DIALOG_TEXT,
51+ DIALOG_MENU_FORE,
52+ DIALOG_MENU_BACK,
53+ DIALOG_BOX,
54+ INPUT_BOX,
55+ INPUT_HEADING,
56+ INPUT_TEXT,
57+ INPUT_FIELD,
58+ FUNCTION_TEXT,
59+ FUNCTION_HIGHLIGHT,
60+ ATTR_MAX
61+} attributes_t;
62+extern attributes_t attributes[];
63+
64+typedef enum {
65+ F_HELP = 1,
66+ F_SYMBOL = 2,
67+ F_INSTS = 3,
68+ F_CONF = 4,
69+ F_BACK = 5,
70+ F_SAVE = 6,
71+ F_LOAD = 7,
72+ F_EXIT = 8
73+} function_key;
74+
75+void set_colors(void);
76+
77+/* this changes the windows attributes !!! */
78+void print_in_middle(WINDOW *win,
79+ int starty,
80+ int startx,
81+ int width,
82+ const char *string,
83+ chtype color);
84+int get_line_length(const char *line);
85+int get_line_no(const char *text);
86+const char *get_line(const char *text, int line_no);
87+void fill_window(WINDOW *win, const char *text);
88+int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...);
89+int dialog_inputbox(WINDOW *main_window,
90+ const char *title, const char *prompt,
91+ const char *init, char *result, int result_len);
92+void refresh_all_windows(WINDOW *main_window);
93+void show_scroll_win(WINDOW *main_window,
94+ const char *title,
95+ const char *text);
scripts/kconfig/symbol.c+18−12
@@ -651,12 +651,20 @@ bool sym_is_changable(struct symbol *sym) · 650 unmodified lines
651651 return sym->visible > sym->rev_dep.tri;
652652 }
653653
654+static unsigned strhash(const char *s)
655+{
656+ /* fnv32 hash */
657+ unsigned hash = 2166136261U;
658+ for (; *s; s++)
659+ hash = (hash ^ *s) * 0x01000193;
660+ return hash;
661+}
662+
654663 struct symbol *sym_lookup(const char *name, int flags)
655664 {
656665 struct symbol *symbol;
657− const char *ptr;
658666 char *new_name;
659− int hash = 0;
667+ int hash;
660668
661669 if (name) {
662670 if (name[0] && !name[1]) {
@@ -666,12 +674,11 @@ struct symbol *sym_lookup(const char *name, int flags) · 3 unmodified lines
666674 case 'n': return &symbol_no;
667675 }
668676 }
669− for (ptr = name; *ptr; ptr++)
670− hash += *ptr;
671− hash &= 0xff;
677+ hash = strhash(name) % SYMBOL_HASHSIZE;
672678
673679 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
674− if (!strcmp(symbol->name, name) &&
680+ if (symbol->name &&
681+ !strcmp(symbol->name, name) &&
675682 (flags ? symbol->flags & flags
676683 : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
677684 return symbol;
@@ -679,7 +686,7 @@ struct symbol *sym_lookup(const char *name, int flags) · 1 unmodified line
679686 new_name = strdup(name);
680687 } else {
681688 new_name = NULL;
682− hash = 256;
689+ hash = 0;
683690 }
684691
685692 symbol = malloc(sizeof(*symbol));
@@ -697,7 +704,6 @@ struct symbol *sym_lookup(const char *name, int flags) · 11 unmodified lines
697704 struct symbol *sym_find(const char *name)
698705 {
699706 struct symbol *symbol = NULL;
700− const char *ptr;
701707 int hash = 0;
702708
703709 if (!name)
@@ -710,12 +716,11 @@ struct symbol *sym_find(const char *name) · 6 unmodified lines
710716 case 'n': return &symbol_no;
711717 }
712718 }
713− for (ptr = name; *ptr; ptr++)
714− hash += *ptr;
715− hash &= 0xff;
719+ hash = strhash(name) % SYMBOL_HASHSIZE;
716720
717721 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
718− if (!strcmp(symbol->name, name) &&
722+ if (symbol->name &&
723+ !strcmp(symbol->name, name) &&
719724 !(symbol->flags & SYMBOL_CONST))
720725 break;
721726 }
@@ -750,6 +755,7 @@ struct symbol **sym_re_search(const char *pattern) · 28 unmodified lines
750755 return NULL;
751756 }
752757 }
758+ sym_calc_value(sym);
753759 sym_arr[cnt++] = sym;
754760 }
755761 if (sym_arr)
scripts/kconfig/util.c+2−0
@@ -78,6 +78,7 @@ struct gstr str_new(void) · 77 unmodified lines
7878 struct gstr gs;
7979 gs.s = malloc(sizeof(char) * 64);
8080 gs.len = 64;
81+ gs.max_width = 0;
8182 strcpy(gs.s, "\0");
8283 return gs;
8384 }
@@ -88,6 +89,7 @@ struct gstr str_assign(const char *s) · 4 unmodified lines
8889 struct gstr gs;
8990 gs.s = strdup(s);
9091 gs.len = strlen(s) + 1;
92+ gs.max_width = 0;
9193 return gs;
9294 }
9395
scripts/kconfig/zconf.tab.c_shipped+19−6
@@ -104,7 +104,7 @@ static void zconf_error(const char *err, ...); · 103 unmodified lines
104104 static void zconferror(const char *err);
105105 static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
106106
107−struct symbol *symbol_hash[257];
107+struct symbol *symbol_hash[SYMBOL_HASHSIZE];
108108
109109 static struct menu *current_menu, *current_entry;
110110
@@ -2220,7 +2220,7 @@ void conf_parse(const char *name) · 2109 unmodified lines
22202220 zconf_initscan(name);
22212221
22222222 sym_init();
2223− menu_init();
2223+ _menu_init();
22242224 modules_sym = sym_lookup(NULL, 0);
22252225 modules_sym->type = S_BOOLEAN;
22262226 modules_sym->flags |= SYMBOL_AUTO;
@@ -2336,9 +2336,9 @@ static void print_symbol(FILE *out, struct menu *menu) · 109 unmodified lines
23362336 struct property *prop;
23372337
23382338 if (sym_is_choice(sym))
2339− fprintf(out, "choice\n");
2339+ fprintf(out, "\nchoice\n");
23402340 else
2341− fprintf(out, "config %s\n", sym->name);
2341+ fprintf(out, "\nconfig %s\n", sym->name);
23422342 switch (sym->type) {
23432343 case S_BOOLEAN:
23442344 fputs(" boolean\n", out);
@@ -2384,6 +2384,21 @@ static void print_symbol(FILE *out, struct menu *menu) · 39 unmodified lines
23842384 case P_CHOICE:
23852385 fputs(" #choice value\n", out);
23862386 break;
2387+ case P_SELECT:
2388+ fputs( " select ", out);
2389+ expr_fprint(prop->expr, out);
2390+ fputc('\n', out);
2391+ break;
2392+ case P_RANGE:
2393+ fputs( " range ", out);
2394+ expr_fprint(prop->expr, out);
2395+ fputc('\n', out);
2396+ break;
2397+ case P_MENU:
2398+ fputs( " menu ", out);
2399+ print_quoted_string(out, prop->text);
2400+ fputc('\n', out);
2401+ break;
23872402 default:
23882403 fprintf(out, " unknown prop %d!\n", prop->type);
23892404 break;
@@ -2395,7 +2410,6 @@ static void print_symbol(FILE *out, struct menu *menu) · 5 unmodified lines
23952410 menu->help[len] = 0;
23962411 fprintf(out, " help\n%s\n", menu->help);
23972412 }
2398− fputc('\n', out);
23992413 }
24002414
24012415 void zconfdump(FILE *out)
@@ -2428,7 +2442,6 @@ void zconfdump(FILE *out) · 26 unmodified lines
24282442 expr_fprint(prop->visible.expr, out);
24292443 fputc('\n', out);
24302444 }
2431− fputs("\n", out);
24322445 }
24332446
24342447 if (menu->list)
scripts/kconfig/zconf.y+19−6
@@ -27,7 +27,7 @@ static void zconf_error(const char *err, ...); · 26 unmodified lines
2727 static void zconferror(const char *err);
2828 static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
2929
30−struct symbol *symbol_hash[257];
30+struct symbol *symbol_hash[SYMBOL_HASHSIZE];
3131
3232 static struct menu *current_menu, *current_entry;
3333
@@ -475,7 +475,7 @@ void conf_parse(const char *name) · 441 unmodified lines
475475 zconf_initscan(name);
476476
477477 sym_init();
478− menu_init();
478+ _menu_init();
479479 modules_sym = sym_lookup(NULL, 0);
480480 modules_sym->type = S_BOOLEAN;
481481 modules_sym->flags |= SYMBOL_AUTO;
@@ -591,9 +591,9 @@ static void print_symbol(FILE *out, struct menu *menu) · 109 unmodified lines
591591 struct property *prop;
592592
593593 if (sym_is_choice(sym))
594− fprintf(out, "choice\n");
594+ fprintf(out, "\nchoice\n");
595595 else
596− fprintf(out, "config %s\n", sym->name);
596+ fprintf(out, "\nconfig %s\n", sym->name);
597597 switch (sym->type) {
598598 case S_BOOLEAN:
599599 fputs(" boolean\n", out);
@@ -639,6 +639,21 @@ static void print_symbol(FILE *out, struct menu *menu) · 39 unmodified lines
639639 case P_CHOICE:
640640 fputs(" #choice value\n", out);
641641 break;
642+ case P_SELECT:
643+ fputs( " select ", out);
644+ expr_fprint(prop->expr, out);
645+ fputc('\n', out);
646+ break;
647+ case P_RANGE:
648+ fputs( " range ", out);
649+ expr_fprint(prop->expr, out);
650+ fputc('\n', out);
651+ break;
652+ case P_MENU:
653+ fputs( " menu ", out);
654+ print_quoted_string(out, prop->text);
655+ fputc('\n', out);
656+ break;
642657 default:
643658 fprintf(out, " unknown prop %d!\n", prop->type);
644659 break;
@@ -650,7 +665,6 @@ static void print_symbol(FILE *out, struct menu *menu) · 5 unmodified lines
650665 menu->help[len] = 0;
651666 fprintf(out, " help\n%s\n", menu->help);
652667 }
653− fputc('\n', out);
654668 }
655669
656670 void zconfdump(FILE *out)
@@ -683,7 +697,6 @@ void zconfdump(FILE *out) · 26 unmodified lines
683697 expr_fprint(prop->visible.expr, out);
684698 fputc('\n', out);
685699 }
686− fputs("\n", out);
687700 }
688701
689702 if (menu->list)
scripts/markup_oops.pl+39−15
@@ -2,6 +2,7 @@ · 1 unmodified line
22
33 use File::Basename;
44 use Math::BigInt;
5+use Getopt::Long;
56
67 # Copyright 2008, Intel Corporation
78 #
@@ -15,6 +16,16 @@ use Math::BigInt; · 7 unmodified lines
1516 # Arjan van de Ven <arjan@linux.intel.com>
1617
1718
19+my $cross_compile = "";
20+my $vmlinux_name = "";
21+my $modulefile = "";
22+
23+# Get options
24+Getopt::Long::GetOptions(
25+ 'cross-compile|c=s' => \$cross_compile,
26+ 'module|m=s' => \$modulefile,
27+ 'help|h' => \&usage,
28+) || usage ();
1829 my $vmlinux_name = $ARGV[0];
1930 if (!defined($vmlinux_name)) {
2031 my $kerver = `uname -r`;
@@ -23,9 +34,8 @@ if (!defined($vmlinux_name)) { · 2 unmodified lines
2334 print "No vmlinux specified, assuming $vmlinux_name\n";
2435 }
2536 my $filename = $vmlinux_name;
26−#
27−# Step 1: Parse the oops to find the EIP value
28−#
37+
38+# Parse the oops to find the EIP value
2939
3040 my $target = "0";
3141 my $function;
@@ -177,26 +187,26 @@ my $decodestart = Math::BigInt->from_hex("0x$target") - Math::BigInt->from_hex(" · 145 unmodified lines
177187 my $decodestop = Math::BigInt->from_hex("0x$target") + 8192;
178188 if ($target eq "0") {
179189 print "No oops found!\n";
180− print "Usage: \n";
181− print " dmesg | perl scripts/markup_oops.pl vmlinux\n";
182− exit;
190+ usage();
183191 }
184192
185193 # if it's a module, we need to find the .ko file and calculate a load offset
186194 if ($module ne "") {
187− my $modulefile = `modinfo $module | grep '^filename:' | awk '{ print \$2 }'`;
188− chomp($modulefile);
195+ if ($modulefile eq "") {
196+ $modulefile = `modinfo -F filename $module`;
197+ chomp($modulefile);
198+ }
189199 $filename = $modulefile;
190200 if ($filename eq "") {
191201 print "Module .ko file for $module not found. Aborting\n";
192202 exit;
193203 }
194204 # ok so we found the module, now we need to calculate the vma offset
195− open(FILE, "objdump -dS $filename |") || die "Cannot start objdump";
205+ open(FILE, $cross_compile."objdump -dS $filename |") || die "Cannot start objdump";
196206 while (<FILE>) {
197207 if ($_ =~ /^([0-9a-f]+) \<$function\>\:/) {
198208 my $fu = $1;
199− $vmaoffset = hex($target) - hex($fu) - hex($func_offset);
209+ $vmaoffset = Math::BigInt->from_hex("0x$target") - Math::BigInt->from_hex("0x$fu") - Math::BigInt->from_hex("0x$func_offset");
200210 }
201211 }
202212 close(FILE);
@@ -204,7 +214,7 @@ if ($module ne "") { · 1 unmodified line
204214
205215 my $counter = 0;
206216 my $state = 0;
207−my $center = 0;
217+my $center = -1;
208218 my @lines;
209219 my @reglines;
210220
@@ -212,7 +222,7 @@ sub InRange { · 1 unmodified line
212222 my ($address, $target) = @_;
213223 my $ad = "0x".$address;
214224 my $ta = "0x".$target;
215− my $delta = hex($ad) - hex($ta);
225+ my $delta = Math::BigInt->from_hex($ad) - Math::BigInt->from_hex($ta);
216226
217227 if (($delta > -4096) && ($delta < 4096)) {
218228 return 1;
@@ -225,7 +235,7 @@ sub InRange { · 6 unmodified lines
225235 # first, parse the input into the lines array, but to keep size down,
226236 # we only do this for 4Kb around the sweet spot
227237
228−open(FILE, "objdump -dS --adjust-vma=$vmaoffset --start-address=$decodestart --stop-address=$decodestop $filename |") || die "Cannot start objdump";
238+open(FILE, $cross_compile."objdump -dS --adjust-vma=$vmaoffset --start-address=$decodestart --stop-address=$decodestop $filename |") || die "Cannot start objdump";
229239
230240 while (<FILE>) {
231241 my $line = $_;
@@ -236,7 +246,8 @@ while (<FILE>) { · 4 unmodified lines
236246 $state = 1;
237247 }
238248 }
239− } else {
249+ }
250+ if ($state == 1) {
240251 if ($line =~ /^([a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]+)\:/) {
241252 my $val = $1;
242253 if (!InRange($val, $target)) {
@@ -259,7 +270,7 @@ if ($counter == 0) { · 16 unmodified lines
259270 exit;
260271 }
261272
262−if ($center == 0) {
273+if ($center == -1) {
263274 print "No matching code found \n";
264275 exit;
265276 }
@@ -344,3 +355,16 @@ while ($i < $finish) { · 78 unmodified lines
344355 $i = $i +1;
345356 }
346357
358+sub usage {
359+ print <<EOT;
360+Usage:
361+ dmesg | perl $0 [OPTION] [VMLINUX]
362+
363+OPTION:
364+ -c, --cross-compile CROSS_COMPILE Specify the prefix used for toolchain.
365+ -m, --module MODULE_DIRNAME Specify the module filename.
366+ -h, --help Help.
367+EOT
368+ exit;
369+}
370+
scripts/mkcompile_h+2−3
@@ -67,9 +67,8 @@ UTS_TRUNCATE="cut -b -$UTS_LEN" · 66 unmodified lines
6767 echo \#define LINUX_COMPILE_BY \"`whoami`\"
6868 echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\"
6969
70− if [ -x /bin/dnsdomainname ]; then
71− domain=`dnsdomainname 2> /dev/null`
72− elif [ -x /bin/domainname ]; then
70+ domain=`dnsdomainname 2> /dev/null`
71+ if [ -z "$domain" ]; then
7372 domain=`domainname 2> /dev/null`
7473 fi
7574
scripts/mod/modpost.c+88−64
@@ -781,10 +781,13 @@ static void check_section(const char *modname, struct elf_info *elf, · 780 unmodified lines
781781 #define ALL_EXIT_TEXT_SECTIONS \
782782 ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$"
783783
784−#define ALL_INIT_SECTIONS INIT_SECTIONS, DEV_INIT_SECTIONS, \
785− CPU_INIT_SECTIONS, MEM_INIT_SECTIONS
786−#define ALL_EXIT_SECTIONS EXIT_SECTIONS, DEV_EXIT_SECTIONS, \
787− CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS
784+#define ALL_XXXINIT_SECTIONS DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, \
785+ MEM_INIT_SECTIONS
786+#define ALL_XXXEXIT_SECTIONS DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, \
787+ MEM_EXIT_SECTIONS
788+
789+#define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS
790+#define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS
788791
789792 #define DATA_SECTIONS ".data$", ".data.rel$"
790793 #define TEXT_SECTIONS ".text$"
@@ -814,33 +817,29 @@ static const char *data_sections[] = { DATA_SECTIONS, NULL }; · 23 unmodified lines
814817
815818
816819 /* symbols in .data that may refer to init/exit sections */
817−static const char *symbol_white_list[] =
818−{
819− "*driver",
820− "*_template", /* scsi uses *_template a lot */
821− "*_timer", /* arm uses ops structures named _timer a lot */
822− "*_sht", /* scsi also used *_sht to some extent */
823− "*_ops",
824− "*_probe",
825− "*_probe_one",
826− "*_console",
827− NULL
828−};
820+#define DEFAULT_SYMBOL_WHITE_LIST \
821+ "*driver", \
822+ "*_template", /* scsi uses *_template a lot */ \
823+ "*_timer", /* arm uses ops structures named _timer a lot */ \
824+ "*_sht", /* scsi also used *_sht to some extent */ \
825+ "*_ops", \
826+ "*_probe", \
827+ "*_probe_one", \
828+ "*_console"
829829
830830 static const char *head_sections[] = { ".head.text*", NULL };
831831 static const char *linker_symbols[] =
832832 { "__init_begin", "_sinittext", "_einittext", NULL };
833833
834834 enum mismatch {
835− NO_MISMATCH,
836− TEXT_TO_INIT,
837− DATA_TO_INIT,
838− TEXT_TO_EXIT,
839− DATA_TO_EXIT,
840− XXXINIT_TO_INIT,
841− XXXEXIT_TO_EXIT,
842− INIT_TO_EXIT,
843− EXIT_TO_INIT,
835+ TEXT_TO_ANY_INIT,
836+ DATA_TO_ANY_INIT,
837+ TEXT_TO_ANY_EXIT,
838+ DATA_TO_ANY_EXIT,
839+ XXXINIT_TO_SOME_INIT,
840+ XXXEXIT_TO_SOME_EXIT,
841+ ANY_INIT_TO_ANY_EXIT,
842+ ANY_EXIT_TO_ANY_INIT,
844843 EXPORT_TO_INIT_EXIT,
845844 };
846845
@@ -848,6 +847,7 @@ struct sectioncheck { · 1 unmodified line
848847 const char *fromsec[20];
849848 const char *tosec[20];
850849 enum mismatch mismatch;
850+ const char *symbol_white_list[20];
851851 };
852852
853853 const struct sectioncheck sectioncheck[] = {
@@ -857,80 +857,103 @@ const struct sectioncheck sectioncheck[] = { · 3 unmodified lines
857857 {
858858 .fromsec = { TEXT_SECTIONS, NULL },
859859 .tosec = { ALL_INIT_SECTIONS, NULL },
860− .mismatch = TEXT_TO_INIT,
860+ .mismatch = TEXT_TO_ANY_INIT,
861+ .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
861862 },
862863 {
863864 .fromsec = { DATA_SECTIONS, NULL },
864− .tosec = { ALL_INIT_SECTIONS, NULL },
865− .mismatch = DATA_TO_INIT,
865+ .tosec = { ALL_XXXINIT_SECTIONS, NULL },
866+ .mismatch = DATA_TO_ANY_INIT,
867+ .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
868+},
869+{
870+ .fromsec = { DATA_SECTIONS, NULL },
871+ .tosec = { INIT_SECTIONS, NULL },
872+ .mismatch = DATA_TO_ANY_INIT,
873+ .symbol_white_list = {
874+ "*_template", "*_timer", "*_sht", "*_ops",
875+ "*_probe", "*_probe_one", "*_console", NULL
876+ },
866877 },
867878 {
868879 .fromsec = { TEXT_SECTIONS, NULL },
869880 .tosec = { ALL_EXIT_SECTIONS, NULL },
870− .mismatch = TEXT_TO_EXIT,
881+ .mismatch = TEXT_TO_ANY_EXIT,
882+ .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
871883 },
872884 {
873885 .fromsec = { DATA_SECTIONS, NULL },
874886 .tosec = { ALL_EXIT_SECTIONS, NULL },
875− .mismatch = DATA_TO_EXIT,
887+ .mismatch = DATA_TO_ANY_EXIT,
888+ .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
876889 },
877890 /* Do not reference init code/data from devinit/cpuinit/meminit code/data */
878891 {
879− .fromsec = { DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, MEM_INIT_SECTIONS, NULL },
892+ .fromsec = { ALL_XXXINIT_SECTIONS, NULL },
880893 .tosec = { INIT_SECTIONS, NULL },
881− .mismatch = XXXINIT_TO_INIT,
894+ .mismatch = XXXINIT_TO_SOME_INIT,
895+ .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
882896 },
883897 /* Do not reference cpuinit code/data from meminit code/data */
884898 {
885899 .fromsec = { MEM_INIT_SECTIONS, NULL },
886900 .tosec = { CPU_INIT_SECTIONS, NULL },
887− .mismatch = XXXINIT_TO_INIT,
901+ .mismatch = XXXINIT_TO_SOME_INIT,
902+ .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
888903 },
889904 /* Do not reference meminit code/data from cpuinit code/data */
890905 {
891906 .fromsec = { CPU_INIT_SECTIONS, NULL },
892907 .tosec = { MEM_INIT_SECTIONS, NULL },
893− .mismatch = XXXINIT_TO_INIT,
908+ .mismatch = XXXINIT_TO_SOME_INIT,
909+ .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
894910 },
895911 /* Do not reference exit code/data from devexit/cpuexit/memexit code/data */
896912 {
897− .fromsec = { DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS, NULL },
913+ .fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
898914 .tosec = { EXIT_SECTIONS, NULL },
899− .mismatch = XXXEXIT_TO_EXIT,
915+ .mismatch = XXXEXIT_TO_SOME_EXIT,
916+ .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
900917 },
901918 /* Do not reference cpuexit code/data from memexit code/data */
902919 {
903920 .fromsec = { MEM_EXIT_SECTIONS, NULL },
904921 .tosec = { CPU_EXIT_SECTIONS, NULL },
905− .mismatch = XXXEXIT_TO_EXIT,
922+ .mismatch = XXXEXIT_TO_SOME_EXIT,
923+ .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
906924 },
907925 /* Do not reference memexit code/data from cpuexit code/data */
908926 {
909927 .fromsec = { CPU_EXIT_SECTIONS, NULL },
910928 .tosec = { MEM_EXIT_SECTIONS, NULL },
911− .mismatch = XXXEXIT_TO_EXIT,
929+ .mismatch = XXXEXIT_TO_SOME_EXIT,
930+ .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
912931 },
913932 /* Do not use exit code/data from init code */
914933 {
915934 .fromsec = { ALL_INIT_SECTIONS, NULL },
916935 .tosec = { ALL_EXIT_SECTIONS, NULL },
917− .mismatch = INIT_TO_EXIT,
936+ .mismatch = ANY_INIT_TO_ANY_EXIT,
937+ .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
918938 },
919939 /* Do not use init code/data from exit code */
920940 {
921941 .fromsec = { ALL_EXIT_SECTIONS, NULL },
922942 .tosec = { ALL_INIT_SECTIONS, NULL },
923− .mismatch = EXIT_TO_INIT,
943+ .mismatch = ANY_EXIT_TO_ANY_INIT,
944+ .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
924945 },
925946 /* Do not export init/exit functions or data */
926947 {
927948 .fromsec = { "__ksymtab*", NULL },
928949 .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
929− .mismatch = EXPORT_TO_INIT_EXIT
950+ .mismatch = EXPORT_TO_INIT_EXIT,
951+ .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
930952 }
931953 };
932954
933−static int section_mismatch(const char *fromsec, const char *tosec)
955+static const struct sectioncheck *section_mismatch(
956+ const char *fromsec, const char *tosec)
934957 {
935958 int i;
936959 int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck);
@@ -939,10 +962,10 @@ static int section_mismatch(const char *fromsec, const char *tosec) · 2 unmodified lines
939962 for (i = 0; i < elems; i++) {
940963 if (match(fromsec, check->fromsec) &&
941964 match(tosec, check->tosec))
942− return check->mismatch;
965+ return check;
943966 check++;
944967 }
945− return NO_MISMATCH;
968+ return NULL;
946969 }
947970
948971 /**
@@ -961,7 +984,7 @@ static int section_mismatch(const char *fromsec, const char *tosec) · 12 unmodified lines
961984 * Pattern 2:
962985 * Many drivers utilise a *driver container with references to
963986 * add, remove, probe functions etc.
964− * These functions may often be marked __init and we do not want to
987+ * These functions may often be marked __devinit and we do not want to
965988 * warn here.
966989 * the pattern is identified by:
967990 * tosec = init or exit section
@@ -982,7 +1005,8 @@ static int section_mismatch(const char *fromsec, const char *tosec) · 14 unmodified lines
9821005 * refsymname = __init_begin, _sinittext, _einittext
9831006 *
9841007 **/
985−static int secref_whitelist(const char *fromsec, const char *fromsym,
1008+static int secref_whitelist(const struct sectioncheck *mismatch,
1009+ const char *fromsec, const char *fromsym,
9861010 const char *tosec, const char *tosym)
9871011 {
9881012 /* Check for pattern 1 */
@@ -994,7 +1018,7 @@ static int secref_whitelist(const char *fromsec, const char *fromsym, · 5 unmodified lines
9941018 /* Check for pattern 2 */
9951019 if (match(tosec, init_exit_sections) &&
9961020 match(fromsec, data_sections) &&
997− match(fromsym, symbol_white_list))
1021+ match(fromsym, mismatch->symbol_white_list))
9981022 return 0;
9991023
10001024 /* Check for pattern 3 */
@@ -1155,7 +1179,8 @@ static int is_function(Elf_Sym *sym) · 154 unmodified lines
11551179 * Try to find symbols near it so user can find it.
11561180 * Check whitelist before warning - it may be a false positive.
11571181 */
1158−static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1182+static void report_sec_mismatch(const char *modname,
1183+ const struct sectioncheck *mismatch,
11591184 const char *fromsec,
11601185 unsigned long long fromaddr,
11611186 const char *fromsym,
@@ -1186,8 +1211,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, · 24 unmodified lines
11861211 modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec,
11871212 tosym, to_p);
11881213
1189− switch (mismatch) {
1190− case TEXT_TO_INIT:
1214+ switch (mismatch->mismatch) {
1215+ case TEXT_TO_ANY_INIT:
11911216 fprintf(stderr,
11921217 "The function %s%s() references\n"
11931218 "the %s %s%s%s.\n"
@@ -1197,8 +1222,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, · 3 unmodified lines
11971222 to, sec2annotation(tosec), tosym, to_p,
11981223 fromsym, sec2annotation(tosec), tosym);
11991224 break;
1200− case DATA_TO_INIT: {
1201− const char **s = symbol_white_list;
1225+ case DATA_TO_ANY_INIT: {
1226+ const char *const *s = mismatch->symbol_white_list;
12021227 fprintf(stderr,
12031228 "The variable %s references\n"
12041229 "the %s %s%s%s\n"
@@ -1211,15 +1236,15 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, · 6 unmodified lines
12111236 fprintf(stderr, "\n");
12121237 break;
12131238 }
1214− case TEXT_TO_EXIT:
1239+ case TEXT_TO_ANY_EXIT:
12151240 fprintf(stderr,
12161241 "The function %s() references a %s in an exit section.\n"
12171242 "Often the %s %s%s has valid usage outside the exit section\n"
12181243 "and the fix is to remove the %sannotation of %s.\n",
12191244 fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym);
12201245 break;
1221− case DATA_TO_EXIT: {
1222− const char **s = symbol_white_list;
1246+ case DATA_TO_ANY_EXIT: {
1247+ const char *const *s = mismatch->symbol_white_list;
12231248 fprintf(stderr,
12241249 "The variable %s references\n"
12251250 "the %s %s%s%s\n"
@@ -1232,8 +1257,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, · 6 unmodified lines
12321257 fprintf(stderr, "\n");
12331258 break;
12341259 }
1235− case XXXINIT_TO_INIT:
1236− case XXXEXIT_TO_EXIT:
1260+ case XXXINIT_TO_SOME_INIT:
1261+ case XXXEXIT_TO_SOME_EXIT:
12371262 fprintf(stderr,
12381263 "The %s %s%s%s references\n"
12391264 "a %s %s%s%s.\n"
@@ -1243,7 +1268,7 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, · 3 unmodified lines
12431268 to, sec2annotation(tosec), tosym, to_p,
12441269 tosym, fromsym, tosym);
12451270 break;
1246− case INIT_TO_EXIT:
1271+ case ANY_INIT_TO_ANY_EXIT:
12471272 fprintf(stderr,
12481273 "The %s %s%s%s references\n"
12491274 "a %s %s%s%s.\n"
@@ -1256,7 +1281,7 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, · 6 unmodified lines
12561281 to, sec2annotation(tosec), tosym, to_p,
12571282 sec2annotation(tosec), tosym, to_p);
12581283 break;
1259− case EXIT_TO_INIT:
1284+ case ANY_EXIT_TO_ANY_INIT:
12601285 fprintf(stderr,
12611286 "The %s %s%s%s references\n"
12621287 "a %s %s%s%s.\n"
@@ -1275,8 +1300,6 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, · 12 unmodified lines
12751300 "Fix this by removing the %sannotation of %s "
12761301 "or drop the export.\n",
12771302 tosym, sec2annotation(tosec), sec2annotation(tosec), tosym);
1278− case NO_MISMATCH:
1279− /* To get warnings on missing members */
12801303 break;
12811304 }
12821305 fprintf(stderr, "\n");
@@ -1286,11 +1309,11 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf, · 3 unmodified lines
12861309 Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
12871310 {
12881311 const char *tosec;
1289− enum mismatch mismatch;
1312+ const struct sectioncheck *mismatch;
12901313
12911314 tosec = sec_name(elf, sym->st_shndx);
12921315 mismatch = section_mismatch(fromsec, tosec);
1293− if (mismatch != NO_MISMATCH) {
1316+ if (mismatch) {
12941317 Elf_Sym *to;
12951318 Elf_Sym *from;
12961319 const char *tosym;
@@ -1302,7 +1325,8 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf, · 5 unmodified lines
13021325 tosym = sym_name(elf, to);
13031326
13041327 /* check whitelist - we may ignore it */
1305− if (secref_whitelist(fromsec, fromsym, tosec, tosym)) {
1328+ if (secref_whitelist(mismatch,
1329+ fromsec, fromsym, tosec, tosym)) {
13061330 report_sec_mismatch(modname, mismatch,
13071331 fromsec, r->r_offset, fromsym,
13081332 is_function(from), tosec, tosym,
scripts/namespace.pl+33−32
@@ -175,12 +175,11 @@ sub do_nm · 174 unmodified lines
175175 }
176176 if (! -e "$source.c" && ! -e "$source.S") {
177177 # No obvious source, exclude the object if it is conglomerate
178− if (! open(OBJDUMPDATA, "$objdump $basename|")) {
179− printf STDERR "$objdump $fullname failed $!\n";
180− return;
181− }
178+ open(my $objdumpdata, "$objdump $basename|")
179+ or die "$objdump $fullname failed $!\n";
180+
182181 my $comment;
183− while (<OBJDUMPDATA>) {
182+ while (<$objdumpdata>) {
184183 chomp();
185184 if (/^In archive/) {
186185 # Archives are always conglomerate
@@ -190,18 +189,18 @@ sub do_nm · 3 unmodified lines
190189 next if (! /^[ 0-9a-f]{5,} /);
191190 $comment .= substr($_, 43);
192191 }
193− close(OBJDUMPDATA);
192+ close($objdumpdata);
193+
194194 if (!defined($comment) || $comment !~ /GCC\:.*GCC\:/m) {
195195 printf STDERR "No source file found for $fullname\n";
196196 }
197197 return;
198198 }
199− if (! open(NMDATA, "$nm $basename|")) {
200− printf STDERR "$nm $fullname failed $!\n";
201− return;
202− }
199+ open (my $nmdata, "$nm $basename|")
200+ or die "$nm $fullname failed $!\n";
201+
203202 my @nmdata;
204− while (<NMDATA>) {
203+ while (<$nmdata>) {
205204 chop;
206205 ($type, $name) = (split(/ +/, $_, 3))[1..2];
207206 # Expected types
@@ -268,7 +267,8 @@ sub do_nm · 60 unmodified lines
268267 }
269268 }
270269 }
271− close(NMDATA);
270+ close($nmdata);
271+
272272 if ($#nmdata < 0) {
273273 if (
274274 $fullname ne "lib/brlock.o"
@@ -316,8 +316,7 @@ sub drop_def · 41 unmodified lines
316316
317317 sub list_multiply_defined
318318 {
319− my ($name, $module);
320− foreach $name (keys(%def)) {
319+ foreach my $name (keys(%def)) {
321320 if ($#{$def{$name}} > 0) {
322321 # Special case for cond_syscall
323322 if ($#{$def{$name}} == 1 && $name =~ /^sys_/ &&
@@ -333,8 +332,9 @@ sub list_multiply_defined · 9 unmodified lines
333332 &drop_def("arch/x86/kernel/vsyscall-sysenter_32.o", $name);
334333 next;
335334 }
335+
336336 printf "$name is multiply defined in :-\n";
337− foreach $module (@{$def{$name}}) {
337+ foreach my $module (@{$def{$name}}) {
338338 printf "\t$module\n";
339339 }
340340 }
@@ -343,12 +343,13 @@ sub list_multiply_defined · 2 unmodified lines
343343
344344 sub resolve_external_references
345345 {
346− my ($object, $type, $name, $i, $j, $kstrtab, $ksymtab, $export);
346+ my ($kstrtab, $ksymtab, $export);
347+
347348 printf "\n";
348− foreach $object (keys(%nmdata)) {
349+ foreach my $object (keys(%nmdata)) {
349350 my $nmdata = $nmdata{$object};
350− for ($i = 0; $i <= $#{$nmdata}; ++$i) {
351− ($type, $name) = split(' ', $nmdata->[$i], 2);
351+ for (my $i = 0; $i <= $#{$nmdata}; ++$i) {
352+ my ($type, $name) = split(' ', $nmdata->[$i], 2);
352353 if ($type eq "U" || $type eq "w") {
353354 if (exists($def{$name}) || exists($ksymtab{$name})) {
354355 # add the owning object to the nmdata
@@ -357,7 +358,7 @@ sub resolve_external_references · 2 unmodified lines
357358 $kstrtab = "R __kstrtab_$name";
358359 $ksymtab = "R __ksymtab_$name";
359360 $export = 0;
360− for ($j = 0; $j <= $#{$nmdata}; ++$j) {
361+ for (my $j = 0; $j <= $#{$nmdata}; ++$j) {
361362 if ($nmdata->[$j] eq $kstrtab ||
362363 $nmdata->[$j] eq $ksymtab) {
363364 $export = 1;
@@ -424,11 +425,11 @@ sub resolve_external_references · 60 unmodified lines
424425 sub list_extra_externals
425426 {
426427 my %noref = ();
427− my ($name, @module, $module, $export);
428− foreach $name (keys(%def)) {
428+
429+ foreach my $name (keys(%def)) {
429430 if (! exists($ref{$name})) {
430− @module = @{$def{$name}};
431− foreach $module (@module) {
431+ my @module = @{$def{$name}};
432+ foreach my $module (@module) {
432433 if (! exists($noref{$module})) {
433434 $noref{$module} = [];
434435 }
@@ -438,16 +439,16 @@ sub list_extra_externals · 3 unmodified lines
438439 }
439440 if (%noref) {
440441 printf "\nExternally defined symbols with no external references\n";
441− foreach $module (sort(keys(%noref))) {
442+ foreach my $module (sort(keys(%noref))) {
442443 printf " $module\n";
443444 foreach (sort(@{$noref{$module}})) {
444− if (exists($export{$_})) {
445− $export = " (export only)";
446− }
447− else {
448− $export = "";
449− }
450− printf " $_$export\n";
445+ my $export;
446+ if (exists($export{$_})) {
447+ $export = " (export only)";
448+ } else {
449+ $export = "";
450+ }
451+ printf " $_$export\n";
451452 }
452453 }
453454 }
scripts/package/builddeb+2−0
@@ -18,6 +18,8 @@ create_package() { · 17 unmodified lines
1818 cp debian/copyright "$pdir/usr/share/doc/$pname/"
1919 cp debian/changelog "$pdir/usr/share/doc/$pname/changelog.Debian"
2020 gzip -9 "$pdir/usr/share/doc/$pname/changelog.Debian"
21+ sh -c "cd '$pdir'; find . -type f ! -path './DEBIAN/*' -printf '%P\0' \
22+ | xargs -r0 md5sum > DEBIAN/md5sums"
2123
2224 # Fix ownership and permissions
2325 chown -R root:root "$pdir"
scripts/package/mkspec+1−1
@@ -39,7 +39,7 @@ if ! $PREBUILT; then · 38 unmodified lines
3939 echo "Source: kernel-$__KERNELRELEASE.tar.gz"
4040 fi
4141
42−echo "BuildRoot: /var/tmp/%{name}-%{PACKAGE_VERSION}-root"
42+echo "BuildRoot: %{_tmppath}/%{name}-%{PACKAGE_VERSION}-root"
4343 echo "Provides: $PROVIDES"
4444 echo "%define __spec_install_post /usr/lib/rpm/brp-compress || :"
4545 echo "%define debug_package %{nil}"
scripts/profile2linkerlist.pl+3−5
@@ -7,15 +7,13 @@ · 6 unmodified lines
77 # usage:
88 # readprofile | sort -rn | perl profile2linkerlist.pl > functionlist
99 #
10+use strict;
1011
1112 while (<>) {
1213 my $line = $_;
1314
1415 $_ =~ /\W*[0-9]+\W*([a-zA-Z\_0-9]+)\W*[0-9]+/;
1516
16− if ( ($line =~ /unknown/) || ($line =~ /total/)) {
17−
18− } else {
19− print "*(.text.$1)\n";
20− }
17+ print "*(.text.$1)\n"
18+ unless ($line =~ /unknown/) || ($line =~ /total/);
2119 }
scripts/rt-tester/rt-tester.py+1−1
@@ -1,4 +1,4 @@
1−#!/usr/bin/env python
1+#!/usr/bin/python
22 #
33 # rt-mutex tester
44 #
scripts/show_delta+1−1
@@ -1,4 +1,4 @@
1−#!/usr/bin/env python
1+#!/usr/bin/python
22 #
33 # show_deltas: Read list of printk messages instrumented with
44 # time data, and format with time deltas.
scripts/tags.sh+30−15
@@ -5,7 +5,7 @@ · 4 unmodified lines
55 # mode may be any of: tags, TAGS, cscope
66 #
77 # Uses the following environment variables:
8−# ARCH, SUBARCH, srctree, src, obj
8+# ARCH, SUBARCH, SRCARCH, srctree, src, obj
99
1010 if [ "$KBUILD_VERBOSE" = "1" ]; then
1111 set -x
@@ -17,28 +17,48 @@ ignore="( -name SCCS -o -name BitKeeper -o -name .svn -o \ · 5 unmodified lines
1717 -name .git ) \
1818 -prune -o"
1919
20−# Do not use full path is we do not use O=.. builds
20+# Do not use full path if we do not use O=.. builds
21+# Use make O=. {tags|cscope}
22+# to force full paths for a non-O= build
2123 if [ "${KBUILD_SRC}" = "" ]; then
2224 tree=
2325 else
2426 tree=${srctree}/
2527 fi
2628
29+# Find all available archs
30+find_all_archs()
31+{
32+ ALLSOURCE_ARCHS=""
33+ for arch in `ls ${tree}arch`; do
34+ ALLSOURCE_ARCHS="${ALLSOURCE_ARCHS} "${arch##\/}
35+ done
36+}
37+
2738 # Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH
2839 if [ "${ALLSOURCE_ARCHS}" = "" ]; then
2940 ALLSOURCE_ARCHS=${SRCARCH}
41+elif [ "${ALLSOURCE_ARCHS}" = "all" ]; then
42+ find_all_archs
3043 fi
3144
3245 # find sources in arch/$ARCH
3346 find_arch_sources()
3447 {
35− find ${tree}arch/$1 $ignore -name "$2" -print;
48+ for i in $archincludedir; do
49+ prune="$prune -wholename $i -prune -o"
50+ done
51+ find ${tree}arch/$1 $ignore $prune -name "$2" -print;
3652 }
3753
3854 # find sources in arch/$1/include
3955 find_arch_include_sources()
4056 {
41− find ${tree}arch/$1/include $ignore -name "$2" -print;
57+ include=$(find ${tree}arch/$1/ -name include -type d);
58+ if [ -n "$include" ]; then
59+ archincludedir="$archincludedir $include"
60+ find $include $ignore -name "$2" -print;
61+ fi
4262 }
4363
4464 # find sources in include/
@@ -63,14 +83,15 @@ find_sources() · 18 unmodified lines
6383
6484 all_sources()
6585 {
66− for arch in $ALLSOURCE_ARCHS
67− do
68− find_sources $arch '*.[chS]'
69− done
86+ find_arch_include_sources ${SRCARCH} '*.[chS]'
7087 if [ ! -z "$archinclude" ]; then
7188 find_arch_include_sources $archinclude '*.[chS]'
7289 fi
7390 find_include_sources '*.[chS]'
91+ for arch in $ALLSOURCE_ARCHS
92+ do
93+ find_sources $arch '*.[chS]'
94+ done
7495 find_other_sources '*.[chS]'
7596 }
7697
@@ -89,13 +110,7 @@ all_defconfigs() · 12 unmodified lines
89110
90111 docscope()
91112 {
92− # always use absolute paths for cscope, as recommended by cscope
93− # upstream
94− case "$tree" in
95− /*) ;;
96− *) tree=$PWD/$tree ;;
97− esac
98− (cd /; echo \-k; echo \-q; all_sources) > cscope.files
113+ (echo \-k; echo \-q; all_sources) > cscope.files
99114 cscope -b -f cscope.out
100115 }
101116