home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / boot / i386 / rescue / usr / bin / mkinfodir < prev    next >
Text File  |  2006-11-29  |  8KB  |  374 lines

  1. #!/usr/bin/perl
  2. # Copyright (c) 1996-2003 SuSE Linux AG, Nuernberg, Germany.
  3. # All rights reserved.
  4. #
  5. # Author: Werner Fink <werner@suse.de>, 1996,1997,2003
  6. #
  7. # MAKEDIR.perl  --- Version 0.54
  8. #
  9.  
  10. use bytes;
  11.  
  12. if ( $#ARGV > 0 ) {
  13.     printf(STDERR "%s: Usage:\n", $0);
  14.     printf(STDERR "  %s [info_dir_file]\n", $0); exit(1);
  15. }
  16.  
  17. if ( length($ENV{'INFOPATH'}) > 0 ) {
  18.     @PATHS = split(/:/, $ENV{'INFOPATH'});
  19. }
  20. @PATHS=(
  21. #
  22. # /usr/share/info is the first in Path because it's our main info dir!
  23. #
  24.          "/usr/share/info",
  25.          "/usr/info",
  26. #
  27. # Insert INFOPATH
  28. #
  29.          @PATHS,
  30.          "/usr/lib/info",
  31. #
  32. # TeTeX-Infos are looked in by symbolic links in /usr/info.
  33. #
  34. #         "/usr/lib/teTeX/info",
  35.          "/usr/local/info",
  36.          "/usr/local/lib/info",
  37.          "/usr/X11R6/info",
  38.          "/usr/X11R6/lib/info",
  39. #
  40. # xemacs has big problems handling nodes of the same name but
  41. # different paths ... it's really buggy.
  42. #
  43.          "/usr/X11R6/lib/xemacs/info",
  44.          "/usr/share/xemacs/xemacs-packages/info",
  45.          "/usr/share/xemacs/mule-packages/info",
  46.          "/usr/share/xemacs/info",
  47. );
  48. #
  49. # Special: flushing file descriptor for speed, smothing, and big results
  50. #
  51. sub flush {
  52.     local($old) = select(shift);
  53.     $| = 1;
  54.     print "";
  55.     $| = 0;
  56.     select($old);
  57. }
  58.  
  59. #
  60. # Open the main dir file
  61. #
  62. $rand = int(rand(32767));
  63. if ( $#ARGV == 0 ) {
  64.     $mdir    = "$ARGV[0]";
  65.     $mdirbak = "$ARGV[0].bak";
  66.     $mdirtmp = "$ARGV[0].tmp$$.$rand";
  67. } else {
  68.     $mdir    = "$PATHS[0]/dir";
  69.     $mdirbak = "$PATHS[0]/dir.bak";
  70.     $mdirtmp = "$PATHS[0]/dir.tmp$$.$rand";
  71. }
  72.  
  73. sub cleanup {
  74.     unlink $mdirtmp;
  75.     exit(1);
  76. }
  77. $SIG{'INT'}  = "cleanup";
  78. $SIG{'TERM'} = "cleanup";
  79. $SIG{'HUP'}  = "cleanup";
  80. $SIG{'PIPE'} = 'IGNORE';
  81.  
  82. if ( !-e $mdir ) { `touch $mdir 2>&1 /dev/null`; }
  83.  
  84. if ( -w $mdir ) {
  85.     # sysopen(FH, $mdirtmp, O_RDWR|O_CREAT|O_EXCL) or die "Cannot create $mdirtmp\n";
  86.     # close(FH);
  87.     if ( -s $mdir && !-e $mdirbak ) {
  88.     `cp -p $mdir $mdirbak`;
  89.     if ( !-e $mdirbak ) { exit(1); }
  90.     }
  91.     `cp -p $mdir $mdirtmp`;
  92.     if ( !-e $mdirtmp ) { exit(1); }
  93.     $filehandle = ">$mdir" ;
  94. } else {
  95.     printf(STDERR "%s: Warning, can not write to %s\n", $0, $mdir);
  96.     printf(STDERR "  ... using STDOUT!\n");
  97.     flush(STDERR);
  98.     sleep (2);
  99.     $filehandle = ">-";
  100. }
  101.  
  102. ##
  103. ## read info dir
  104. ##
  105. @allinfo = ();
  106. %found   = ();
  107. for ( @PATHS ) {
  108.     @info = ();
  109.     $found{$_}++;
  110.     if ( $found{$_} > 1 ) {
  111.     next;
  112.     }
  113.     (-e $_) && (@info = ( -d $_ ) ? ( <$_/*> ) : ( $_ ));
  114.     @info = grep(/[^0-9](|\.gz)$/, @info);
  115.     @info = grep(!/(dir|dir\.bak|localdir|\~|\,v|\.orig)(|\.gz)$/, @info);
  116.     @info = sort grep(!/-\d+\./, @info);
  117.     push(@allinfo, @info);
  118. }
  119.  
  120. sub basename {
  121.     local($name) = @_;
  122.     $name =~ s!.*/!!;
  123.     $name =~ s/\.gz//;
  124.     $name =~ s/\.info//;
  125.     $name =~ s/\+/\\\\+/g;
  126.  
  127.     return ($name);
  128. }
  129.  
  130. sub path {
  131.     local($name) = @_;
  132.     $name =~ s!\/[^/]*$!!;
  133.  
  134.     return ($name);
  135. }
  136.  
  137. ##
  138. ##
  139. ## Global section titles used as keys
  140. ##
  141. ##
  142. @sec = ();
  143.  
  144. #
  145. # Reformat if required
  146. #
  147. sub do_format {
  148.     local($node, @buf) =  @_;
  149.     local($base) =  basename($node);
  150.     local($path) =  path($node);
  151.     local($name) = "";
  152.     local($desc) = "";
  153.     local($link) = "";
  154.     local($l, $first, @ent);
  155.  
  156.     $node =~ s/\.gz$//;
  157.     $node =~ s/\.info$//;
  158.     $node =~ s!//!/!g;
  159.  
  160.     if ( $path =~ /^$PATHS[0]$/ ) { $node = $base; }
  161.  
  162.     @ent = ();
  163.     foreach $l (@buf) {
  164.     $first = index($l,"*");
  165.  
  166.     $l =~ s/\($base\)/\($node\)/g;
  167.     $l =~ s/::/: \($node\)\./g;
  168.  
  169.     $name = "";
  170.     $desc = "";
  171.     $link = "";
  172.  
  173.     ($name,$desc) = split(/\.\s+/,"$l");
  174.  
  175.     $name =~ s/\n//g;
  176.     $name =~ s/\s+$//g;
  177.     $name =~ s/^\s+//g;
  178.  
  179.     $desc =~ s/\n//g;
  180.     $desc =~ s/\s+$//g;
  181.     $desc =~ s/^\s+//g;
  182.  
  183.     if ( $first == 0 ) {
  184.         $l =~ s/^(\s+)//g;
  185.         ($name, $link) = split(/:/, $name);
  186.         $name =~ s/\s+$//g;
  187.         $link =~ s/^\s+//g;
  188.         $link =~ s/\.$//g;
  189.         $name = $name . ':' . ' ' . $link . '.';
  190.         if ( length($l) > 80 ) {
  191.         if ( length($name) < 16 && length($desc) < 62) {
  192.              $l = sprintf("%-16.18s%s", $name, $desc);
  193.         } else {
  194.             if ( length($desc) > 0 ) {
  195.             $l = sprintf("%s\n\t\t%s", $name, $desc);
  196.             } else {
  197.             $l = sprintf("%s", $name);
  198.             }
  199.         }
  200.         }
  201.     }
  202.     push(@ent, $l);
  203.     }
  204.     return join("\n", @ent);
  205. }
  206.  
  207. #
  208. # No info for entry found, use old or make a new one
  209. #
  210. sub guess_missed {
  211.     local($node) =  @_;
  212.     local($base) =  basename($node);
  213.     local($path) =  path($node);
  214.     local($cur)  = "default";
  215.     local($ldir);
  216.     local(@buf, $add, $lines);
  217.  
  218.     $node =~ s/\.gz$//;
  219.     $node =~ s/\.info$//;
  220.     $node =~ s!//!/!g;
  221.  
  222.     if ( $path =~ /^$PATHS[0]$/ ) { $node = $base; }
  223.  
  224.     if ( $path !~ /^$PATHS[0]$/ ) {
  225.     $ldir = "$path/dir";
  226.     } else {
  227.     $ldir = $mdirtmp;
  228.     }
  229.  
  230.     @buf = ();
  231.     if ( -e $ldir && -r $ldir ) {
  232.     open(FILE, $ldir);
  233.     $add = 0;
  234.     while (<FILE>) {
  235.         #
  236.         # read next few lines if there is information ($add == 1)
  237.         #
  238.         if ( $add == 1 ) {
  239.         if ( /^\s+[^\:\*]+$/ ) {
  240.             push(@buf, $_); $lines++;
  241.             next;
  242.         }
  243.         last;
  244.         }
  245.         if      ( /^\*\s+$base\:\s+\($base\)\.\s+\w/i ) {
  246.         $add = 1; push(@buf, $_); $lines = 1;
  247.         } elsif ( /^\*\s+$base\:\:\s+\w/i ) {
  248.         $add = 1; push(@buf, $_); $lines = 1;
  249.         } elsif ( /^\*\s+$base\:\s+\($base\)\.\s+$/i ) {
  250.         $add = 1; push(@buf, $_); $lines = 0;
  251.         } elsif ( /^\*\s+$base\:\:\s+$/i ) {
  252.         $add = 1; push(@buf, $_); $lines = 0;
  253.         } else {
  254.         next;
  255.         }
  256.     }
  257.     close(FILE);
  258.     }
  259.  
  260.     if ($lines > 0) {
  261.     $sec{$cur} = join("\n", $sec{$cur}, do_format($node, @buf));
  262.     } else {
  263.     $base =~ s!(.*)!\L$1!;
  264.     $base =~ s!(.*)!\u$1!;
  265.     $base  = '* ' . $base . ':';
  266.     $sec{$cur} = join("\n", $sec{$cur},
  267.         sprintf("%-0.80s %s\n", $base, '(' . $node . ').'));
  268.     }
  269. }
  270.  
  271. #
  272. # read info file for entry in dir file
  273. #
  274. sub read_entry {
  275.     local($file) = @_;
  276.     local($add, $lines, @buf);
  277.     local($cur) = "default";
  278.     local($source) = $file =~ /\.gz$/ ? "gunzip -q -d -c $file 2>/dev/null |" : "< $file";
  279.     local(@buf);
  280.  
  281.     $add = 0;
  282.     $lines = 0;
  283.     @buf = ();
  284.     open(_FILE, $source) or warn "can't open $source\n";
  285.     while (<_FILE>) {
  286.     chomp;
  287.     s/\s+$//;
  288.     last if ( /^($|File:)/ );
  289.     next if ( /^$/ );
  290.     if ( /^INFO-DIR-SECTION/o )  {
  291.         s/^INFO-DIR-SECTION\s+//;
  292.         $cur = $_;
  293.         next;
  294.     }
  295.     if ( /^START-INFO-DIR-ENTRY/o ) {
  296.         $add = 1;
  297.         push(@buf, "\n") if ( $cur =~ /default/ );
  298.         next;
  299.     }
  300.     if ( /^END-INFO-DIR-ENTRY/o ) {
  301.         $add = 0;
  302.         $sec{$cur} = join("\n", $sec{$cur}, do_format($file, @buf));
  303.         next;
  304.     }
  305.     if ( $add == 1 ) {
  306.         $lines++;
  307.         push(@buf, $_);
  308.         next;
  309.     }
  310.     }
  311.     close(_FILE);
  312.  
  313.     guess_missed($file) if ( $lines == 0 );
  314. }
  315.  
  316. #
  317. # Do all the stuff
  318. #
  319. foreach $elem (@allinfo) {
  320.     read_entry($elem) if ( -f $elem );
  321. }
  322.  
  323. open(DIR, "$filehandle") or die "Cannot open $filehandle\n";
  324. binmode DIR;
  325.  
  326. ##
  327. ## define top format
  328. ##
  329. format DIR =
  330. -*- Text -*-
  331. This is the file /usr/info/dir, which contains the topmost node of the
  332. Info hierarchy.  The first time you invoke Info you start off
  333. looking at that node, which is (dir)Top.
  334. 
  335. File: dir    Node: Top    This is the top of the INFO tree
  336.  
  337.   This (the Directory node) gives a menu of major topics.
  338.  
  339.   Usage in info-mode of EMACS:
  340.     Typing "d" returns here,       typing "?" lists all INFO commands,
  341.     typing "q" exits,     typing "h" gives a  primer for first-timers,
  342.     pressing 2nd button on a highlighted word follows cross-reference.
  343.  
  344.  ---- AUTOCONFIGURED BY SuSEConfig: EDIT WITH CARE: ----
  345.  ---- Only descriptive text for otherwise empty topics will survive ----
  346.  
  347. * Menu: The list of major topics begins on the next line.
  348.  
  349. .
  350. ##
  351. ## end top format
  352. ##
  353. write DIR; # write top format
  354. flush(DIR);
  355.  
  356. @sec = sort keys %sec;
  357. @keys = keys %sec;
  358.  
  359. while ($#keys >= 0) {
  360.     $cur = pop(@keys);
  361.     if ( $cur =~ /default/ ) {
  362.     printf(DIR "\nVarious Utilities");
  363.     } else {
  364.     printf(DIR "\n%s", $cur);
  365.     }
  366.     printf(DIR "%s\n", $sec{$cur});
  367. }
  368.  
  369. printf(DIR "\n* Locales:\n");
  370. close(DIR);
  371.  
  372. unlink($mdirtmp) if ( -e $mdirtmp );
  373. exit 0;
  374.