.B install\-info
[\-\-version] [\-\-help] [\-\-debug] [\-\-maxwidth=nnn]
[\-\-section regexp title] [\-\-infodir=xxx] [\-\-align=nnn]
-[\-\-quiet] [\-\-menuentry=xxx] [\-\-description=xxx] [\-\-remove]
+[\-\-quiet] [\-\-menuentry=xxx] [\-\-description=xxx]
+[\-\-remove | \-\-remove-exactly ]
[\-\-] filename
.SH DESCRIPTION
.PP
.TP
.BI "[\-\-] " filename
Gives the filename of the Info file whose menu entry is to be created,
-updated or removed. The basename of this filename is used as the
-referent of the menu entry which is created. This file must therefore
-exist (or be about to be installed, or have previously existed when
-removing an entry) in the same directory as the
+updated or removed. If
+.B \-\-remove-exactly
+is specified, then
+.I filename
+should be the exact entry name to be removed (i.e. "emacs-20/emacs" or
+"gcc"), otherwise the basename of this filename is used as the
+referent of the menu entry which is created, unless there's an
+overriding START-INFO-DIR entry inside the given file. This file must
+therefore exist (or be about to be installed, or have previously
+existed when removing an entry) in the same directory as the
.B dir
file (see the
.B \-\-infodir
.BR \-\-maxwidth ", " \-\-align " and " \-\-calign
formatting options are silently ignored.
.TP
+.B \-\-remove-exactly
+This option is essentially the same as
+.B \-\-remove
+except that
+.I filename
+is taken as the exact entry to be removed, rather than as the name
+of an existing file. This can be important when trying to remove
+entries that refer to info files in subdirectories
+(i.e. "emacs-20/emacs") because
+.B \-\-remove
+will operate on the basename of the given
+.I filename
+rather than the exact name given. (i.e.
+.B \-\-remove
+"emacs-20/emacs" would cause
+.B install-info
+to look for "emacs", not "emacs-20/emacs").
+.TP
.BI "\-\-section " "regexp title"
Specifies that, if a new entry is to be made, it should be placed in a
section of the
usage: install-info [--version] [--help] [--debug] [--maxwidth=nnn]
[--section regexp title] [--infodir=xxx] [--align=nnn]
[--calign=nnn] [--quiet] [--menuentry=xxx] [--info-dir=xxx]
- [--keep-old] [--description=xxx] [--test] [--remove] [--]
+ [--keep-old] [--description=xxx] [--test]
+ [--remove | --remove-exactly ]
+ [--]
filename
END
}
$debug=0;
$remove=0;
+my $remove_exactly;
+
$0 =~ m|[^/]+$|; $name= $&;
while ($ARGV[0] =~ m/^--/) {
$keepold=1;
} elsif ($_ eq '--remove') {
$remove=1;
+ } elsif ($_ eq '--remove-exactly') {
+ $remove=1;
+ $remove_exactly=1;
} elsif ($_ eq '--help') {
&usage; exit 0;
} elsif ($_ eq '--debug') {
umask(umask(0777) & ~0444);
+if($remove_exactly) {
+ $remove_exactly = $filename;
+}
+
$filename =~ m|[^/]+$|; $basename= $&; $basename =~ s/(\.info)?(\.gz)?$//;
+
+# The location of the info files from the dir entry, i.e. (emacs-20/emacs).
+my $fileinentry;
+
&dprint("infodir='$infodir' filename='$filename' maxwidth='$maxwidth'\nmenuentry='$menuentry' basename='$basename'\ndescription='$description' remove=$remove");
if (!$remove) {
}
while(<IF>) { last if m/^END-INFO-DIR-ENTRY$/; $asread.= $_; }
close(IF); &checkpipe;
- if ($asread =~ m/(\* *[^:]+: *\([^\)]+\).*\. *.*\n){2,}/) {
- $infoentry= $asread; $multiline= 1;
+ if ($asread =~ m/(\*\s*[^:]+:\s*\(([^\)]+)\).*\. *.*\n){2,}/) {
+ $infoentry= $asread;
+ $multiline= 1;
+ $fileinentry = $2;
&dprint("multiline '$asread'");
- } elsif ($asread =~ m/^\* *([^:]+):( *\([^\)]+\)\.|:)\s*/) {
- $menuentry= $1; $description= $';
+ } elsif ($asread =~ m/^\*\s*([^:]+):(\s*\(([^\)]+)\)\.|:)\s*/) {
+ $menuentry= $1;
+ $description= $';
+ $fileinentry = $3;
&dprint("infile menuentry '$menuentry' description '$description'");
} elsif (length($asread)) {
print STDERR <<END;
$infoentry =~ m/\n/;
print "$`\n" unless $quiet;
- $infoentry =~ m/^\* *([^:]+): *\(([^\)]+)\)/ || die "$name: Invalid info entry\n"; # internal error
- $sortby= $1; $fileinentry= $2;
-
+ $infoentry =~ m/^\*\s*([^:]+):\s*\(([^\)]+)\)/ ||
+ die "$name: Invalid info entry\n"; # internal error
+ $sortby= $1;
+ $fileinentry= $2;
+
} else {
if (!length($description)) {
}
if (!length($description)) {
- print STDERR <<END;
+ print STDERR "
No \`START-INFO-DIR-ENTRY' and no \`This file documents'.
$name: unable to determine description for \`dir' entry - giving up
-END
+";
exit 1;
}
&dprint("menuentry='$menuentry' description='$description'");
- $cprefix= sprintf("* %s: (%s).", $menuentry, $basename);
+ if($fileinentry) {
+ $cprefix= sprintf("* %s: (%s).", $menuentry, $fileinentry);
+ } else {
+ $cprefix= sprintf("* %s: (%s).", $menuentry, $basename);
+ }
+
$align--; $calign--;
$lprefix= length($cprefix);
if ($lprefix < $align) {
if (!$remove) {
+ my $target_entry;
+
+ if($fileinentry) {
+ $target_entry = $fileinentry;
+ } else {
+ $target_entry = $basename;
+ }
+
for ($i=0; $i<=$#work; $i++) {
- next unless $work[$i] =~ m/^\* *[^:]+: *\(([^\)]+)\).*\.\s/;
- last if $1 eq $basename || $1 eq "$basename.info";
+ next unless $work[$i] =~ m/^\*\s*[^:]+:\s*\(([^\)]+)\).*\.\s/;
+ last if $1 eq $target_entry || $1 eq "$target_entry.info";
}
for ($j=$i; $j<=$#work+1; $j++) {
next if $work[$j] =~ m/^\s+\S/;
last unless $work[$j] =~ m/^\* *[^:]+: *\(([^\)]+)\).*\.\s/;
- last unless $1 eq $basename || $1 eq "$basename.info";
+ last unless $1 eq $target_entry || $1 eq "$target_entry.info";
}
if ($i < $j) {
if ($keepold) {
- print "$name: existing entry for \`$basename' not replaced\n" unless $quiet;
+ print "$name: existing entry for \`$target_entry' not replaced\n" unless $quiet;
$nowrite=1;
} else {
- print "$name: replacing existing dir entry for \`$basename'\n" unless $quiet;
+ print "$name: replacing existing dir entry for \`$target_entry'\n" unless $quiet;
}
$mss= $i;
@work= (@work[0..$i-1], @work[$j..$#work]);
} else {
+ my $target_entry;
+
+ if($remove_exactly) {
+ $target_entry = $remove_exactly;
+ } else {
+ $target_entry = $basename;
+ }
+
for ($i=0; $i<=$#work; $i++) {
next unless $work[$i] =~ m/^\* *([^:]+): *\((\w[^\)]*)\)/;
$tme= $1; $tfile= $2; $match= $&;
- next unless $tfile eq $basename;
+ next unless $tfile eq $target_entry;
last if !length($menuentry);
$tme =~ y/A-Z/a-z/;
last if $tme eq $menuentry;
next if $work[$j] =~ m/^\s+\S/;
last unless $work[$j] =~ m/^\* *([^:]+): *\((\w[^\)]*)\)/;
$tme= $1; $tfile= $2;
- last unless $tfile eq $basename;
+ last unless $tfile eq $target_entry;
next if !length($menuentry);
$tme =~ y/A-Z/a-z/;
last unless $tme eq $menuentry;
}
@work= (@work[0..$i-1], @work[$j..$#work]);
} else {
- print "$name: no entry for file \`$basename'".
+ print "$name: no entry for file \`$target_entry'".
(length($menuentry) ? " and menu entry \`$menuentry'": '').
".\n"
unless $quiet;