|
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
This is a subroutine library for a larger program. The library is
supposed to read through GNU `info' files. The instructions that came
with it say:
To use the functions: Call
&open_info_file(INFO_FILENAME);
to open the filehandle `INFO' to the named info file.
Then call
&get_next_node;
repeatedly to read the next node in the info file; the variables
$info_file
$info_node
$info_prev
$info_next
$info_up
are set if the corresponding fields appear in the node's
header, and if the node has a menu, it is loaded into
%info_menu. When `get_next-node' returns false, you have
reached end-of-file or there has been an error.
Those if you with linux boxes probably have an example of an info file
handy. I did not include one here because I thought it might be more
interesting for the people who had not seen one to deduce the
structure of the file from the code below.
One final note: This code was taken from a comp.lang.perl posting
from around 1994. I reproduce it exactly typograhical errors and all.
================================================================
# Read next node into global variables. Assumes that file pointer is
# positioned at the header line that starts a node. Leaves file
# pointer positioned at header line of next node.
# Programmer: note that nodes are separated by a "\n\037\n" sequence.
# Reutrn true on success, false on failure
sub read_next_node {
undef %info_menu;
$_ = <INFO>; # Header line
if (eof(INFO)) {
return &start_next_part && &read_next_node;
}
($info_file) = /File:\s*([^,]*)/;
($info_node) = /Node:\s*([^,]*)/;
($info_prev) = /Prev:\s*([^,]*)/;
($info_next) = /Next:\s*([^,]*)/;
($info_up) = /Up:\s*([^,]*)/;
$_ = <INFO> until /^(\* Menu:|\037)/ || eof(INFO);
if (eof(INFO)) {
return &start_next_part;
} elsif (/^\037/) {
return 1; # end of node, so return success.
}
# read menu
local($key, $ref);
while (<INFO>) {
return 1 if /^\037/; # end of node, menu is finished, success.
next unless /^\* \S/; # next unless lines is a menu item
if (/^\* ([^:]*)::/) {
$key = $ref = $1;
} elsif (/^\* ([^:]*):\s*([^.]*)[.]/) {
($key, $ref) = ($1, $2);
} else {
print STDERR "Couldn't parse menu item\n\t$_";
next;
}
$info_menu{$key} = $ref;
}
# end-of-file also terminates the node successfully.
# start up the next file before continuing.
&start_next_part;
return 1;
}
# Discard commentary before first node of info file
sub start_info_file {
$_ = <INFO> until (/^\037/ || eof(INFO));
return &start_next_part if (eof(INFO)) ;
return 1;
}
# Look for next part of multi-part info file.
# Return 0 (normal failure) if it isn't there---that just means
# we ran out of parts. die on some other kind of failure.
sub start_next_part {
local($path, $basename, $ext);
if ($info_filename =~ /\//) {
($path, $basename) = ( $info_filename =~ /^(.*)\/(.*)$/ );
} else {
$basename = $info_filename;
$path = "";
}
if ($basename =~ /-\d*$/) {
($basename, $ext) = ($basename =~ /^([^-]*)-(\d*)$/);
} else {
$ext = 0;
}
$ext++;
$info_filename = "$path/$basename-$ext";
close(INFO);
if (! (open(INFO, "$info_filename")) ) {
if ($! eq "No such file or directory") {
return 0;
} else {
die "Couldn't open $info_filename: $!";
}
}
return &start_info_file;
}
sub open_info_file {
($info_filename) = @_;
(open(INFO, "$info_filename")) || die "Couldn't open $info_filename: $!";
return &start_info_file;
}
**Majordomo list services provided by PANIX <URL:http://www.panix.com>**
**To Unsubscribe, send "unsubscribe phl" to majordomo@lists.pm.org**
|
|