Patch: 2.1.82 Configure.help speedup

Adam Heath (adam@brainiac.egr.msu.edu)
Wed, 28 Jan 1998 13:52:28 -0500 (EST)


This patch build an index of Configure.help, and uses said index to
decrease the extraction time of the help text. On my machine, using the
sed line to get the last option of Configure.help, was slower(by a factor
of 3) then building the index, and extracting the help with this patch.

It is another C script, BTW.

diff -ruN 2.1.82-pure/Makefile 2.1.82/Makefile
--- 2.1.82-pure/Makefile Wed Jan 28 13:26:29 1998
+++ 2.1.82/Makefile Wed Jan 28 13:03:56 1998
@@ -209,27 +209,27 @@
mkdir include/linux/modules; \
fi

-oldconfig: symlinks scripts/split-include
+oldconfig: symlinks config_support_scripts
$(CONFIG_SHELL) scripts/Configure -d arch/$(ARCH)/config.in
if [ -r include/linux/autoconf.h ]; then \
scripts/split-include include/linux/autoconf.h include/config; \
fi

-xconfig: symlinks scripts/split-include
+xconfig: symlinks config_support_scripts
$(MAKE) -C scripts kconfig.tk
wish -f scripts/kconfig.tk
if [ -r include/linux/autoconf.h ]; then \
scripts/split-include include/linux/autoconf.h include/config; \
fi

-menuconfig: include/linux/version.h symlinks scripts/split-include
+menuconfig: include/linux/version.h symlinks config_support_scripts
$(MAKE) -C scripts/lxdialog all
$(CONFIG_SHELL) scripts/Menuconfig arch/$(ARCH)/config.in
if [ -r include/linux/autoconf.h ]; then \
scripts/split-include include/linux/autoconf.h include/config; \
fi

-config: symlinks scripts/split-include
+config: symlinks config_support_scripts
$(CONFIG_SHELL) scripts/Configure arch/$(ARCH)/config.in
if [ -r include/linux/autoconf.h ]; then \
scripts/split-include include/linux/autoconf.h include/config; \
@@ -383,6 +383,8 @@
rm -f $(TOPDIR)/include/linux/modversions.h
rm -rf $(TOPDIR)/include/linux/modules
rm -rf modules
+ rm -f scripts/help
+ rm -rf Documentation/.help.index

distclean: mrproper
rm -f core `find . \( -name '*.orig' -o -name '*.rej' -o -name '*~' \
@@ -396,7 +398,7 @@
sums:
find . -type f -print | sort | xargs sum > .SUMS

-dep-files: scripts/mkdep archdep include/linux/version.h
+dep-files: compile_support_scripts archdep include/linux/version.h
scripts/mkdep init/*.c > .depend
scripts/mkdep `find $(FINDHPATH) -follow -name \*.h ! -name modversions.h -print` > .hdepend
set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i fastdep; done
@@ -438,8 +440,16 @@
# This generates dependencies for the .h files.
#

+config_support_scripts: scripts/split-include scripts/help
+
+compile_support_scripts: scripts/mkdep
+
scripts/mkdep: scripts/mkdep.c
$(HOSTCC) $(HOSTCFLAGS) -o scripts/mkdep scripts/mkdep.c

scripts/split-include: scripts/split-include.c
$(HOSTCC) $(HOSTCFLAGS) -o scripts/split-include scripts/split-include.c
+
+scripts/help: scripts/help.c
+ $(MAKE) -C scripts help
+
diff -ruN 2.1.82-pure/scripts/Configure 2.1.82/scripts/Configure
--- 2.1.82-pure/scripts/Configure Mon Jun 16 19:36:02 1997
+++ 2.1.82/scripts/Configure Wed Jan 28 11:04:59 1998
@@ -83,29 +83,7 @@
# help variable
#
function help () {
- if [ -f Documentation/Configure.help ]
- then
- #first escape regexp special characters in the argument:
- var=$(echo "$1"|sed 's/[][\/.^$*]/\\&/g')
- #now pick out the right help text:
- text=$(sed -n "/^$var[ ]*\$/,\${
- /^$var[ ]*\$/b
- /^#.*/b
- /^[ ]*\$/q
- p
- }" Documentation/Configure.help)
- if [ -z "$text" ]
- then
- echo; echo " Sorry, no help available for this option yet.";echo
- else
- (echo; echo "$text"; echo) | ${PAGER:-more}
- fi
- else
- echo;
- echo " Can't access the file Documentation/Configure.help which"
- echo " should contain the help texts."
- echo
- fi
+ (echo; echo `scripts/help extract $1`; echo) | ${PAGER:-more}
}


@@ -424,12 +402,14 @@
val=""
while [ -z "$val" ]; do
ambg=n
- readln "$question ($names) [$def] " "$def" "$old"
+ readln "$question ($names) [$def/?] " "$def" "$old"
ans=$(echo $ans | tr a-z A-Z)
set -- $choices
while [ -n "$1" ]; do
name=$(echo $1 | tr a-z A-Z)
case "$name" in
+ "\?" ) help "$var"
+ ;;
"$ans"* )
if [ "$name" = "$ans" ]; then
val="$2"
diff -ruN 2.1.82-pure/scripts/Makefile 2.1.82/scripts/Makefile
--- 2.1.82-pure/scripts/Makefile Mon Jan 5 04:41:01 1998
+++ 2.1.82/scripts/Makefile Tue Jan 27 20:01:58 1998
@@ -37,3 +37,6 @@
rm -f *~ kconfig.tk *.o tkparse mkdep split-include

include $(TOPDIR)/Rules.make
+
+help: help.c
+ $(HOSTCC) $(HOSTCFLAGS) -o help help.c
diff -ruN 2.1.82-pure/scripts/Menuconfig 2.1.82/scripts/Menuconfig
--- 2.1.82-pure/scripts/Menuconfig Wed Jan 28 13:26:14 1998
+++ 2.1.82/scripts/Menuconfig Wed Jan 28 11:29:27 1998
@@ -259,49 +259,11 @@

} # END load_functions()

-
-
-
-
-#
-# Extract available help for an option from Configure.help
-# and send it to standard output.
-#
-# Most of this function was borrowed from the original kernel
-# Configure script.
-#
-function extract_help () {
- if [ -f Documentation/Configure.help ]
- then
- #first escape regexp special characters in the argument:
- var=$(echo "$1"|sed 's/[][\/.^$*]/\\&/g')
- #now pick out the right help text:
- text=$(sed -n "/^$var[ ]*\$/,\${
- /^$var[ ]*\$/d
- /^#.*/d
- /^[ ]*\$/q
- s/^ //
- p
- }" Documentation/Configure.help)
-
- if [ -z "$text" ]
- then
- echo "There is no help available for this kernel option."
- return 1
- else
- echo "$text"
- fi
- else
- echo "There is no help available for this kernel option."
- return 1
- fi
-}
-
#
# Activate a help dialog.
#
function help () {
- if extract_help $1 >help.out
+ if scripts/help extract $1 >help.out
then
$DIALOG --backtitle "$backtitle" --title "$2"\
--textbox help.out $ROWS $COLS
diff -ruN 2.1.82-pure/scripts/header.tk 2.1.82/scripts/header.tk
--- 2.1.82-pure/scripts/header.tk Mon Jan 5 04:41:01 1998
+++ 2.1.82/scripts/header.tk Tue Jan 27 20:01:58 1998
@@ -350,45 +350,21 @@
catch {destroy $w}
toplevel $w -class Dialog

- set filefound 0
set found 0
set lineno 0

- if { [file readable Documentation/Configure.help] == 1} then {
- set filefound 1
- set message [exec sed -n "
- /^$var\[ \]*\$/,\${
- /^$var\[ \]*\$/c\\
-${var}:\\
-
- /^#.*/d
- /^\[ \]*\$/bL
- H
- }
- d
- :L x
- s/\\n //
- s/\\n / /g
- p
- q
- " Documentation/Configure.help]
- set found [expr [string length "$message"] > 0]
- }
+ set message [exec scripts/help "extract $var"]
+ set found [expr [string length "$message"] > 0]

frame $w.f1

if { $found == 0 } then {
- if { $filefound == 0 } then {
- message $w.f1.m -width 750 -aspect 300 -relief flat -text \
- "No help available - unable to open file Documentation/Configure.help. This file should have come with your kernel."
- } else {
message $w.f1.m -width 400 -aspect 300 -relief flat -text \
"No help available for $var"
- }
label $w.f1.bm -bitmap error
wm title $w "RTFM"
} else {
- message $w.f1.m -width 400 -aspect 300 -text $message \
+ message $w.f1.m -width 600 -aspect 300 -text $message \
-relief flat
label $w.f1.bm -bitmap info
wm title $w "Configuration help"
diff -ruN 2.1.82-pure/scripts/help.c 2.1.82/scripts/help.c
--- 2.1.82-pure/scripts/help.c Wed Dec 31 19:00:00 1969
+++ 2.1.82/scripts/help.c Wed Jan 28 13:05:23 1998
@@ -0,0 +1,257 @@
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <dirent.h>
+
+#define DEBUG
+#define doc_dir "Documentation"
+#define help_file doc_dir "/Configure.help"
+#define help_index doc_dir "/.help.index"
+#define help_dir doc_dir "/config"
+
+#define no_help_msg "There is no help available for the option."
+#ifdef DEBUG
+ int debug_level=0;
+ #define debug(dlevel,msg...) if(dlevel<=debug_level) fprintf(stderr,msg)
+#else
+ #define debug(dlevel,msg...)
+#endif
+#define print_error(frmt,msg...) fprintf(stderr,"%s: " frmt " %s\n",func_name , ## msg,sys_errlist[errno])
+
+int lof(int fd){
+ struct stat buf;
+
+ if(fstat(fd,&buf))
+ return -1;
+ else
+ return buf.st_size;
+
+}
+void help_add_to_index(const char *helpf,const char *indexf){
+ const char * func_name= "help_add_to_index";
+ int fd;
+
+ caddr_t hfile_mm;
+ FILE *ifile;
+ char * cur_off,*eol;
+ int start_off=0,end_off;
+ char * config_opt=NULL;
+ int mode=0,temp,fs;
+ char * temps;
+
+ debug(1,"adding file(%s) to index.\n",helpf);
+ if((fd=open(helpf,O_RDWR))!=-1){
+ fs=lof(fd);
+ if(((int)hfile_mm=mmap(0,fs,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0))!=-1){
+ if((int)(ifile=fopen(indexf,"a"))!=-1){
+
+ cur_off=hfile_mm;
+
+ while((cur_off-hfile_mm)<fs){
+ eol=memchr(cur_off,'\n',fs-(cur_off-hfile_mm));
+ *eol='\0';
+ if(strncasecmp(cur_off,"CONFIG",6)==0){
+ if(config_opt) free(config_opt);
+ temp=eol-cur_off+1;
+ config_opt=malloc(temp);
+ strncpy(config_opt,cur_off,temp);
+ start_off=eol+1-hfile_mm;
+ if((temps=index(config_opt,' ')))
+ *temps='\0';
+ mode=1;
+ }else
+ if((mode==1)&&(strlen(cur_off)==0)){
+ end_off=cur_off-1-hfile_mm;
+ mode=0;
+ fprintf(ifile,"%s %s %i %i\n",config_opt,helpf,(int)start_off,(int)end_off);
+ }
+ *eol='\n';
+ cur_off=eol+1;
+ }
+ fclose(ifile);
+ }else{
+ print_error("%s",indexf);
+ }
+ munmap((void*)hfile_mm,lof(fd));
+ }else{
+ print_error("mmap %s",helpf);
+ }
+ close(fd);
+ }else{
+ print_error("%s",helpf);
+ }
+
+}
+void help_extract(const char *indexf,const char *token){
+ const char * func_name= "help_extract";
+ int fs,fd;
+ caddr_t hfile_mm,ifile_mm;
+
+ char * start_off,*end_off;
+ int start_off_i,end_off_i;
+ int temp;
+ char * temps,*temps2;
+
+ if((fd=open(indexf,O_RDWR))!=-1){
+ errno=0;
+ fs=lof(fd);
+ if((int)(ifile_mm=mmap(0,fs,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0))!=-1){
+ temps=malloc(temp=strlen(token)+2);
+ strcpy(temps,token);
+ strcat(temps," ");
+ if((temps2=strstr(ifile_mm,temps))){
+ char * helpf,*savef=NULL;
+ int fs,fd,need_open=1;
+
+ helpf=strstr(temps2+1," ")+1;
+ start_off=strstr(helpf+1," ")+1;
+ end_off=strstr(start_off+1," ")+1;
+ start_off_i=atol(start_off);
+ end_off_i=atol(end_off);
+
+ *(start_off-1)='\0';
+ if(savef){
+ if(strcmp(savef,helpf)){
+ munmap((void*)hfile_mm,lof(fd));
+ close(fd);
+ need_open=1;
+ }
+ }
+ if(need_open){
+ fd=open(helpf,O_RDWR);
+ errno=0;
+ fs=lof(fd);
+ hfile_mm=mmap(0,fs,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
+ if(errno) fprintf(stderr,"The was an error mmap'ing\n");
+
+ need_open=0;
+ }
+ temps=malloc(temp=end_off_i-start_off_i+2);
+ temps2=hfile_mm+start_off_i;
+ strncpy(temps,temps2,temp-1);
+ printf(temps);
+
+ if(savef==NULL){
+ savef=malloc(strlen(helpf)+1);
+ strcpy(savef,helpf);
+ }
+ *(start_off-1)=' ';
+ }else
+ printf(no_help_msg);
+ munmap((void*)ifile_mm,fs);
+ }else
+ print_error("mmap %s",indexf);
+ close(fd);
+ }else
+ print_error("%s",indexf);
+}
+void help_add_dir_to_index(const char *dir,const char *indexf){
+ const char * func_name= "help_add_dir_to_index";
+ DIR *dirh;
+ struct dirent * dire;
+ char *tempname;
+
+ debug(1,"adding dir(%s) to index.\n",dir);
+ tempname=malloc(256+strlen(dir)+1);
+ if((dirh=opendir(dir))){
+ struct stat buf;
+ while((dire=readdir(dirh))){
+ strcpy(tempname,dir);
+ strcat(tempname,"/");
+ strcat(tempname,dire->d_name);
+ stat(tempname,&buf);
+ if(S_ISREG(buf.st_mode))
+ help_add_to_index(tempname,help_index);
+ }
+ closedir(dirh);
+ }else
+ print_error("closedir %s",dir);
+
+}
+void help_make_index(int argc,const char * argv[],int c){
+ struct stat buf;
+ int count=c;
+
+ help_add_to_index(help_file,help_index);
+ help_add_dir_to_index(help_dir,help_index);
+
+ while(count<argc){
+ stat(argv[count],&buf);
+ if(S_ISDIR(buf.st_mode))
+ help_add_dir_to_index(argv[count],help_index);
+ else
+ if(S_ISREG(buf.st_mode))
+ help_add_to_index(argv[count],help_index);
+ count++;
+ }
+}
+void help_clean(const char *indexf){
+ const char * func_name= "help_make_index";
+
+ if((unlink(indexf))==-1)
+ print_error("unlink %s",indexf);
+}
+int main(int argc,const char * argv[]){
+ const char * func_name= "main";
+ int c=1;
+
+ if((argc==0))
+ exit(0);
+#ifdef DEBUG
+ while((c <argc)&&(strcmp(argv[c],"debug")==0)){
+ debug_level++;c++;
+ }
+#endif
+ if((strcmp(argv[c],"clean")==0)){
+ help_clean(help_index);
+ return 0;
+ }
+ if((strcmp(argv[c],"add")==0)){
+ help_make_index(argc,argv,c+1);
+ return 0;
+ }
+ if((strcmp(argv[c],"index")==0)){
+ help_clean(help_index);
+ help_make_index(argc,argv,c+1);
+ return 0;
+ }
+ if((strcmp(argv[c],"extract")==0)){
+ struct stat buf;
+ int count=c+1;
+
+ if(stat(help_index,&buf)){
+ if(errno==ENOENT)
+ help_make_index(0,NULL,argc);
+ else
+ print_error("error:index file");
+ }
+ while(count<argc){
+ help_extract(help_index,argv[count]);
+ count++;
+ printf("\n");
+ }
+ return 0;
+ }
+ fprintf(stderr,"Unknown command.\n");
+ fprintf(stderr,"\n");
+ fprintf(stderr,"usage: %s [debug ...] <command> [<opt>]\n",argv[0]);
+ fprintf(stderr,"\n");
+ fprintf(stderr," clean \n");
+ fprintf(stderr," add file-to-add ...\n");
+ fprintf(stderr," index file-to-add ...\n");
+ fprintf(stderr," extract var ...\n");
+#ifdef DEBUG
+ fprintf(stderr," debug increase debugging level\n");
+#endif
+ fprintf(stderr,"\n");
+ fprintf(stderr,"Where\n");
+ fprintf(stderr," file-to-add either a directory or a file.\n");
+ fprintf(stderr," var a CONFIG_* name.\n");
+ fprintf(stderr,"\n");
+}