"Fossies" - the Fresh Open Source Software Archive 
Member "info2html-2.0/info2html" (17 Aug 2006, 25523 Bytes) of package /linux/www/old/info2html-2.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Perl source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 #!/usr/bin/perl
2 #---------------------------------------------------------
3 # info2html
4 #---------------------------------------------------------
5 #
6 # PURPOSE
7 # This perl script converts info nodes to HTML format.
8 # The node is specified on the command line using the
9 # syntax
10 # (<infofile>)<tag>
11 # If <infofile> and/or <tag> are missing, (dir)Top is assumed.
12 #
13 # AUTHOR
14 # Karl Guggisberg <guggis@iam.unibe.ch>
15 #
16 # HISTORY
17 # 11.10.93 V 1.0
18 # 14.10.93 V 1.0a some comments added
19 # 15.10.93 V 1.0b file for configuration settings
20 # 16.10.93 V 1.0c multiple info path possible
21 # some bugs in escaping references removed
22 # 28.6.94 V 1.0d some minor changes
23 # 8.4.95 V 1.1 bug fixes by Tim Witham
24 # <twitham@eng.fm.intel.com>
25 # 1998.05.05 V 1.2 bug fixes, added expires headers, added infocat,
26 # taken over web site maintenance.
27 # Jon Howell <jonh@cs.dartmouth.edu>
28 # 2006-08-16 V 2.0 Output HTML is tidier now. CSS added.
29 # Lots of new config vars added, so old config files
30 # may not work happily unless you tweak them a bit.
31 # Minor bugfixes to the (de)escaping logic.
32 # Minor typoes in comments fixed.
33 #
34 #-------------------------------------------------------
35 require 5; # even though most of the code is in Perl 4 style.
36 $VERSION = "2.0";
37
38 # Getting the full path of the info2html.conf
39 $0 =~ m!(.*/)[^/]+$!;
40 $INFO2HTMLCONF = "$1info2html.conf";
41 require($INFO2HTMLCONF); #-- configuration settings
42
43 use CGI;
44 $ENV{'REQUEST_METHOD'} or
45 print "Note: I'm really supposed to be run as a CGI!\n";
46
47 #-- patterns
48 $NODEBORDER = '\037\014?'; #-- delimiter of an info node
49 $REDIRSEP = '\177'; #-- delimiter in tag tables
50 $WS = '[ \t]+'; #-- white space +
51 $WSS = '[ \t]*'; #-- white space *
52 $TE = '[\t\,\.]'; #-- end of a tag
53 $TAG = '[^\t\,\.]+'; #-- pattern for a tag
54 $FTAG = '[^\)]+'; #-- pattern for a file name in
55 #-- a cross reference
56
57 #---------------------------------------------------------
58 # DieFileNotFound
59 #---------------------------------------------------------
60 # Replies and error message if the file '$FileName' is
61 # not accessible.
62 #---------------------------------------------------------
63 # Don't reveal where we're looking... --jonh 5/20/97 (and reapplied 5/4/1998)
64 sub DieFileNotFound{
65 local($FileName) = @_;
66 #-- TEXT : error message if a file could not be opened
67 print <<"EOF";
68 <html><head><title>Info Files - Error Message</title>
69 $BOTS_STAY_AWAY
70 $HTML_HEAD_STUFF</head><body class='error noopen'>
71 <h1>File IO Error</h1>
72 The Info file could not be opened for reading.
73 </body></html>
74 EOF
75 die "\n";
76 }
77
78 #---------------------------------------------------------
79 # Escape
80 #---------------------------------------------------------
81 sub Escape{
82 local($Tag) = @_;
83 #-- escaping is not needed anymore KG/28.6.94
84 #-- oh yes it is -- jonh 5/16/1997
85
86 $Tag =~ s/ /%20/g; # space
87 $Tag =~ s/\+/%AB/g; # +
88
89 #$Tag;
90 return CGI::escape($Tag);
91 }
92
93 #----------------------------------------------------------
94 # DeEscape
95 #----------------------------------------------------------
96 sub DeEscape{
97 local($Tag) = @_;
98 #-- deescaping is not needed anymore. KG/28.6.94
99 $Tag =~ s/%AB/%2b/g;
100 $Tag =~ s/%20/ /g;
101 #-- oh yes it is -- jonh 5/16/1997
102 #$Tag;
103 return CGI::unescape($Tag);
104 }
105
106 #----------------------------------------------------------
107 # ParsHeaderToken
108 #----------------------------------------------------------
109 # Parses the heaer line of an info node for a specific
110 # link directive (e.g. Up, Prev)
111 #----------------------------------------------------------
112 sub ParsHeaderToken{
113 local($HL,$Token) = @_;
114 local($InfoFile,$Tag,$Temp);
115 return ("","") if $HL !~ /$Token:/; #-- token not available
116 $HL =~ m!$Token:$WS(\(($FTAG)\))!;
117 $InfoFile = $2;
118 $Temp = $2 ne "" ? '\('.$2.'\)' : "";
119 $HL =~ m!$Token:$WS$Temp$WSS([^\t\,\.\n]+)?([\t\,\.\n])!;
120 $Tag = $1 ne "" ? $1 : "Top";
121 return $InfoFile,$Tag;
122 }
123
124 #---------------------------------------------------------
125 # ParsHeaderLine
126 #--------------------------------------------------------
127 # Parses the header line on an info node for all link
128 # directives allowed in a header line.
129 # Sometimes the keyword 'Previous' is found in stead of
130 # 'Prev'. That's why the redirection line is checked
131 # against both of these keywords.
132 #-------------------------------------------------------
133 sub ParsHeaderLine{
134 local($HL) = @_;
135 local(@LinkInfo,@LinkList);
136 #-- Node
137 @LinkInfo = &ParsHeaderToken($HL,"Node");
138 push(@LinkList,@LinkInfo);
139 #-- Next
140 @LinkInfo = &ParsHeaderToken($HL,"Next");
141 push(@LinkList,@LinkInfo);
142 #-- Up
143 @LinkInfo = &ParsHeaderToken($HL,"Up");
144 push(@LinkList,@LinkInfo);
145 #-- Prev or Previous
146 @LinkInfo = &ParsHeaderToken($HL,"Prev");
147 &ParsHeaderToken($HL,"Previous") if $LinkInfo[0] eq "" && $LinkInfo[1] eq "";
148 push(@LinkList,@LinkInfo);
149 return @LinkList;
150 }
151
152 ############################################################
153 # turn tabs into correct number of spaces
154 #
155 sub Tab2Space {
156 local($line) = @_;
157 $line =~ s/^\t/ /; # 8 leading spaces if initial tab
158 while ($line =~ s/^([^\t]+)(\t)/$1 . ' ' x (8 - length($1) % 8)/e) {
159 } # replace each tab with right num of spaces
160 return $line;
161 }
162
163 #--------------------------------------------------------
164 # MenuItem2HTML
165 #--------------------------------------------------------
166 # Transform an info menu item in HTML with references
167 #-------------------------------------------------------
168 sub MenuItem2HTML{
169 local($Line,$BaseInfoFile) = @_;
170 local($MenuLinkTag,$MenuLinkFile,$MenuLinkRef,$MenuLinkText);
171
172 $Line = &Tab2Space($Line); # make sure columns line up well
173
174 if ($Line =~ /\* ([^:]+)::/){ # -- is a simple entry ending with :: ?
175 $MenuLinkTag = $1;
176 $MenuLinkRef = $1;
177 $MenuLinkText = $';
178 $MenuLinkFile = &Escape($BaseInfoFile);
179
180 } elsif ($Line =~ /\* ([^:]+):(\s*\(($FTAG)\)\.?)?(.*)$/) {
181 $MenuLinkFile = $BaseInfoFile;
182 $MenuLinkRef = $1;
183 $MenuLinkText = $4;
184 if ($2) {
185 $MenuLinkFile = $3;
186 $MenuLinkTag = 'Top';
187 $MenuLinkText = ($2 ? ' ' x (length($2)+1) : '') . "$4\n";
188 } else {
189 $Line = "$4\n";
190 if ($Line =~ /( *($TAG)?$TE(.*))$/) {
191 $MenuLinkTag = $2;
192 $MenuLinkText = $Line;
193 }
194 }
195 } else { # can't determine link, just show it
196 return $Line;
197 }
198 $MenuLinkTag = &Escape($MenuLinkTag); # -- escape special chars
199
200 # Yes, we routinely double-escape. Does anyone remember why?
201
202 #-- produce a HTML line
203 return "$MENU_DOT<a class='menux' href=\"$PROGRAM?($MenuLinkFile)$MenuLinkTag\">$MenuLinkRef</a>$MenuLinkText";
204 }
205
206 #-------------------------------------------------------------
207 # ReadIndirectTable
208 #------------------------------------------------------------
209 # Scans an info file for the occurence of an 'Indirect:'
210 # table. Scans the entries and returns two lists with the
211 # filenames and the global offsets.
212 #---------------------------------------------------------
213 sub ReadIndirectTable{
214 local($FileName,*InfoFiles,*Offsets) = @_;
215 local($i,$Next);
216 # open(FH1,$FileName) || &DieFileNotFound($FileName);
217 if ( $FileName =~ /^(.+)\.gz$/ ) {
218 open(FH1,"gunzip < " . $FileName . " 2>/dev/null |") || &DieFileNotFound($FileName);
219 } elsif ( $FileName =~ /^(.+)\.bz2$/ ) {
220 open(FH1,"bzcat " . $FileName . " 2>/dev/null |") || &DieFileNotFound($FileName);
221 } else {
222 open(FH1,$FileName) || &DieFileNotFound($FileName);
223 }
224 #-- scan for start of Indirect: Table
225 while(<FH1>){
226 $Next = <FH1> if /$NODEBORDER/;
227 last if $Next =~ /^Indirect:/i;
228 }
229 $i = 0;
230 #-- scan the entries and setup the arrays
231 while(<FH1>){
232 last if /$NODEBORDER/;
233 if(/([^:]+):[ \t]+(\d+)/){
234 push(@InfoFiles,$1);
235 push(@Offsets,$2);
236 }
237 }
238 close(FH1);
239 }
240
241 #---------------------------------------------------------
242 # ReadTagTable
243 #--------------------------------------------------------
244 # Reads in a tag table from an info file.
245 # Returns an associative array with the tags found.
246 # Tags are transformed to lower case (info is not
247 # case sensitive for tags).
248 # The entries in the associative array are of the
249 # form
250 # <file>#<offset>
251 # <file> may be empty if an indirect table is
252 # present or if the node is located in the
253 # main file.
254 # 'Exists' indicates if a tag table has been found.
255 # 'IsIndirect' indicates if the tag table is based
256 # on a indirect table.
257 #--------------------------------------------------------
258 sub ReadTagTable{
259 local($FileName,*TagList,*Exists,*IsIndirect) = @_;
260 local($File,$Offset);
261
262 if ( $FileName =~ /^(.+)\.gz$/ ) {
263 open(FH,"gunzip < " . $FileName . " 2>/dev/null |") || &DieFileNotFound($FileName);
264 } elsif ( $FileName =~ /^(.+)\.bz2$/ ) {
265 open(FH,"bzcat " . $FileName . " 2>/dev/null |") || &DieFileNotFound($FileName);
266 } else {
267 open(FH,$FileName) || &DieFileNotFound($FileName);
268 }
269
270 $Exists = 0;
271 $IsIndirect = 0;
272 #-- scan for start of tag table
273 while(<FH>){
274 if(/$NODEBORDER/){
275 if (<FH> =~ /^Tag table:/i){
276 $Exists = 1;
277 last;
278 }
279 }
280 }
281 #-- scan the entries
282 while (<FH>){
283 $IsIndirect = 1 if /^\(Indirect\)/i;
284 last if /$NODEBORDER/;
285 /Node:[ \t]+([^$REDIRSEP]+)$REDIRSEP(\d+)/;
286 $Tag = $1;
287 $Tag =~ y/A-Z/a-z/; #-- to lowercase
288 $Offset = $2;
289 if(/File:[ \t]+([^\t,]+)/){
290 $File = $1;
291 }
292 else{
293 $File = "";
294 }
295 $TagList{$Tag} = $File."#".$Offset;
296 }
297 close(FH);
298 }
299
300 #----------------------------------------------------------
301 # ParsCrossRefs
302 #----------------------------------------------------------
303 # scans a line for the existence of cross references and
304 # transforms them to HTML using a little icon
305 #----------------------------------------------------------
306 sub ParsCrossRefs{
307 local($prev,$Line,$BaseInfoFile) = @_;
308 local($*,$NewLine,$Token) = (1);
309 $Line = " ".$Line;
310 if ($prev =~ /\*Note([^\t\,\.]*)$/i) {
311 if ($Line =~ /^$TAG$TE/) {
312 $Line = "$prev-NEWLINE-$Line";
313 }
314 }
315 @Tokens = split(/(\*Note)\s*/i,$Line); # -- split the line
316 while($Token = shift @Tokens){
317 $CrossRefTag = $CrossRefRef = $CrossRefFile = $CrossRefText = '';
318 if($Token !~ /^\*Note/i){ #-- this part is pure text
319 $NewLine .= $Token;
320 next; #-- ... take the next part
321 }
322 $CrossRef = shift(@Tokens);
323 if ($CrossRef !~ /:/){ #-- seems not to be a valid cross ref.
324 $NewLine .= $Token.$CrossRef;
325 next; # -- ... take the next one
326 }
327 if ($CrossRef =~ /^([^:]+)::/){ # -- a simple cross ref..
328 $CrossRefTag = $1;
329 $CrossRefText = $';
330 $CrossRefRef = $CrossRefTag;
331 $CrossRefTag =~ s/-NEWLINE-/ /g;
332 $CrossRefTag =~ s/^\s+//;
333 $CrossRefTag =~ s/\s+/ /g;
334 $CrossRefRef =~ s/-NEWLINE-/\n/g;
335 $CrossRefTag = &Escape($CrossRefTag); # -- escape specials
336 $BaseInfoFile = &Escape($BaseInfoFile);
337 $NewLine .= "<a class='xref' title='a cross reference' href=\"$PROGRAM?($BaseInfoFile)$CrossRefTag\"\n>$CR_URL$CrossRefRef</a>$CrossRefText";
338 next; # -- .. take the next one
339 }
340 if ($CrossRef !~ /$TE/) { # never mind if tag doesn't end on this line
341 $NewLine .= $Token.$CrossRef;
342 next;
343 }
344 #print "--- Com. CR : $CrossRef --- \n";
345 $CrossRef =~ /([^:]+):/; #-- A more complicated one ..
346 $CrossRefRef = $1;
347 $CrossRef = $';
348 $CrossRefText = $CrossRef;
349 if ($CrossRef =~ /^(\s|\n|-NEWLINE-)*\(($FTAG)\)/){ #-- .. with another file ?
350 $CrossRefFile = $2;
351 $CrossRef = $';
352 }
353 $CrossRef =~ /^(\s|\n|-NEWLINE-)*($TAG)?($TE)/; #-- ... and a tag ?
354 $CrossRefTag = $2;
355 if ($CrossRefTag eq "" && $CrossRefFile eq ""){
356 $NewLine .= "*Note : $CrossRefText$3";
357 next;
358 }
359
360 $CrossRefTag =~ s/-NEWLINE-/ /g;
361 $CrossRefTag =~ s/^\s+//;
362 $CrossRefTag =~ s/\s+/ /g;
363 $CrossRefRef =~ s/-NEWLINE-/\n/g;
364 $CrossRefText =~ s/-NEWLINE-/\n/g;
365 $CrossRefFile = $BaseInfoFile if $CrossRefFile eq "";
366 $CrossRefTag = "Top" if $CrossRefTag eq "";
367 $CrossRefRef = "($CrossRefFile)$CrossRefTag" if $CrossRefRef eq '';
368 $CrossRefTag = &Escape($CrossRefTag); #-- escape specials
369 $CrossRefFile = &Escape($CrossRefFile);
370 #-- append the HTML text
371 $NewLine .= "<a class='xref' title='a cross reference' href=\"$PROGRAM?($CrossRefFile)$CrossRefTag\"\n>$CR_URL$CrossRefRef</a>$CrossRefText";
372 }
373 if ($NewLine =~ /\*Note([^\t\,\.]*)$/i) {
374 return "DONTPRINTYET $NewLine";
375 } else {
376 $NewLine; #-- return the new line
377 }
378 }
379
380
381 #-------------------------------------------------------------
382 # PrintLinkInfo
383 #-------------------------------------------------------------
384 # prints the HTML text for a link information in the
385 # header of an info node. Uses some URLs of icons
386 # are specified in 'info2html.conf'.
387 #------------------------------------------------------------
388 sub PrintLinkInfo{
389 local($LinkType,$LinkFile,$LinkTag,$BaseInfoFile,$NoKeys) = @_;
390 local($LinkFileEsc, $LinkAtts);
391 return if $LinkFile eq "" && $LinkTag eq "";
392 $LinkAtts = '';
393 #-- Link Type 'Prev'
394 if ($LinkType =~ /Prev/){
395 $LinkTypeText = $PREV_URL;
396 $LinkAtts = $NoKeys ? " title='$LinkType' "
397 : " accesskey='p' title='alt-p: previous' ";
398 }
399 #-- Link Type 'Up'
400 elsif($LinkType =~ /Up/){
401 $LinkTypeText = $UP_URL;
402 $LinkAtts = $NoKeys ? " title='$LinkType' "
403 : " accesskey='u' title='alt-u: up' ";
404 }
405 #-- Link Type 'Next'
406 elsif($LinkType =~ /Next/){
407 $LinkTypeText = $NEXT_URL;
408 $LinkAtts = $NoKeys ? " title='$LinkType' "
409 : " accesskey='n' title='alt-n: next' ";
410 }
411 #-- If no auxiliary file specified, use the current info file
412 $LinkFile = $LinkFile eq "" ? $BaseInfoFile : $LinkFile;
413 $LinkRef = $LinkTag;
414 $LinkTag = &Escape($LinkTag);
415 $LinkFileEsc = &Escape($LinkFile);
416 #-- print the HTML Text
417 print <<"EOF";
418 <a href="$PROGRAM?($LinkFileEsc)$LinkTag" $LinkAtts
419 >$LinkTypeText
420 <em>$LinkFile:</em> $LinkRef</a>
421 EOF
422 }
423
424 #-------------------------------------------------------------
425 # PrintHeader
426 #-------------------------------------------------------------
427 # Prints the header for an info node in HTML format
428 #------------------------------------------------------------
429 sub PrintHeader{
430 local(*LinkList,$BaseInfoFile) = @_;
431 #-- TEXT for the header of an info node
432
433 local $heading =
434 $LinkList[1] eq 'Top'
435 ? "<h1 class='basetitle'>$BaseInfoFile</h1>"
436 : "<h2><em class='base'>$BaseInfoFile:</em> <span class='section'>$LinkList[1]</span></h2>"
437 ;
438
439 print <<"EOF";
440 <html><head><title>Info: ($BaseInfoFile) $LinkList[1]</title>
441 $HTML_HEAD_STUFF</head><body class='node'>
442 EOF
443
444 print "\n<div class='nav navtop'\n>",
445 "<a href=\"infocat\">$CATALOG_URL Info Catalog</a>\n";
446 &PrintLinkInfo("Prev",$LinkList[6],$LinkList[7],$BaseInfoFile);
447 &PrintLinkInfo("Up", $LinkList[4],$LinkList[5],$BaseInfoFile);
448 &PrintLinkInfo("Next",$LinkList[2],$LinkList[3],$BaseInfoFile);
449
450 print "</div>\n\n$heading";
451
452 print "\n<pre>";
453 return;
454 }
455
456
457 #---------------------------------------------------------
458 # PrintFooter
459 #---------------------------------------------------------
460 # prints the footer for an info node in HTML format
461 #---------------------------------------------------------
462 sub PrintFooter{
463 local(*LinkList,$BaseInfoFile) =@_;
464 #-- TEXT for the footer of an info node
465 print "</pre>\n\n";
466 print "<div class='nav navbottom'\n>",
467 "<a href=\"infocat\">$CATALOG_URL Info Catalog</a>\n";
468 &PrintLinkInfo("Prev",$LinkList[6],$LinkList[7],$BaseInfoFile,1);
469 &PrintLinkInfo("Up", $LinkList[4],$LinkList[5],$BaseInfoFile,1);
470 &PrintLinkInfo("Next",$LinkList[2],$LinkList[3],$BaseInfoFile,1);
471
472 print "</div>\n";
473
474 if($LinkList[1] eq 'Top') {
475 # Let's be modestly concise and show this only on Top pages
476 print <<"EOF";
477 \n<div class='generator'>
478 <hr>
479 <em>automatically generated by </em>
480 <a href="$DOC_URL">info2html v$VERSION</a>
481 </div>
482 EOF
483 } else {
484 print "<!-- info2html v$VERSION -->\n";
485 }
486
487 print "</body></html>\n";
488 return;
489 }
490
491 #----------------------------------------------------------
492 # ReplyNotFoundMessage
493 #----------------------------------------------------------
494 sub ReplyNotFoundMessage{
495 local($FileName,$Tag) = @_;
496 print <<"EOF";
497 <html><head><title>Info Files - Error Message</title>
498 $BOTS_STAY_AWAY
499 $HTML_HEAD_STUFF</head><body class='error nonesuch'>
500 <h1>Error</h1>
501 The Info node <em>$Tag</em> in Info file <em>$FileName</em>
502 does not exist.
503 </body></html>
504 EOF
505 }
506 #-----------------------------------------------------------
507 # InfoNode2HTML
508 #-----------------------------------------------------------
509 # scans an info file for the node with the name '$Tag'
510 # starting at the postion '$Offset'.
511 # If found, the node is translated to HTML and printed.
512 #------------------------------------------------------------
513 sub InfoNode2HTML{
514 local($FileName,$Offset,$Tag,$BaseInfoFile) = @_;
515 local($Found);
516 if ( $FileName =~ /^(.+)\.gz$/ ) {
517 open(FH2,"gunzip < " . $FileName . " 2>/dev/null |") || &DieFileNotFound($FileName);
518 } elsif ( $FileName =~ /^(.+)\.bz2$/ ) {
519 open(FH2,"bzcat " . $FileName . " 2>/dev/null |") || &DieFileNotFound($FileName);
520 } else {
521 open(FH2,$FileName) || &DieFileNotFound($FileName);
522 }
523 seek(FH2,$Offset,0);
524 $Tag =~ y/A-Z/a-z/; # -- to lowercase
525 #-- scan for the node start
526 $Found = 0;
527 while(<FH2>){
528 if (/$NODEBORDER/){
529 $Line = <FH2>;
530 @LinkList = &ParsHeaderLine($Line);
531 $CompareTag = $Tag;
532 $CompareTag =~ s/([^0-9A-Za-z])/\\$1/g; #-- escape special chars !
533 $Temp = $LinkList[1];
534 $Temp =~ y/A-Z/a-z/; #-- to lower case
535 if($Temp =~ /^\s*$CompareTag\s*$/){ #-- node start found ?
536 $Found = 1;
537 last;
538 }
539 }
540 }
541 if($Found == 0){ # -- break if not found
542 &ReplyNotFoundMessage($FileName,$Tag);
543 return;
544 }
545 &PrintHeader(*LinkList,$BaseInfoFile);
546 $InMenu = 0;
547 while(<FH2>){
548 last if /$NODEBORDER/;
549 #-- replace metacharacters
550 s/&/&/g;
551 s/>/>/g;
552 s/</</g;
553 if (/^\* Menu/ && $InMenu ==0){ # -- start of menu section ?
554 $InMenu = 1;
555 print "</pre>\n<h3>Menu</h3>\n<pre class='menu'>";
556 }
557 elsif (/^\* / && $InMenu == 1){ #-- a menu entry ?
558 $Line = &MenuItem2HTML($_,$BaseInfoFile);
559 print $Line;
560 }
561 else { #-- a normal line, just replace cross refs
562 $Line = &ParsCrossRefs($prev,$_,$BaseInfoFile);
563 if ($Line =~ /^DONTPRINTYET (.*)$/) {
564 $prev = $1;
565 } else {
566 $prev = $Line;
567 $Line =~ s!- (Variable|Function|Macro|Command|Special Form|User Option):.*$!<em>$&</em>!;
568 print $Line;
569 }
570 }
571 }
572 close(FH2);
573 &PrintFooter(*LinkList,$BaseInfoFile);
574 }
575
576 #-------------------------------------------------------------
577 # max
578 #------------------------------------------------------------
579 sub max{
580 local($a,$b) = @_;
581 return $a >= $b ? $a : $b;
582 }
583
584 #-----------------------------------------------------------
585 # GetFileAndOffset
586 #------------------------------------------------------------
587 # This procedure locates a specific node in a info file
588 # The location is based on the tag and indirect table in
589 # basic info file if such tables are available.
590 # Because the offsets specified in the tag and in the
591 # indirect tables are more or less inaccurate, the computed
592 # offset is set back 100 bytes. From this position
593 # the specified node will be looked for sequentially.
594 #------------------------------------------------------------
595 sub GetFileAndOffset{
596 local($BaseInfoFile,$NodeName) = @_;
597 local($Exists,$IsIndirect,$File,$Offset,$FileOffset);
598 $NodeName =~ y/A-Z/a-z/;
599 &ReadIndirectTable($BaseInfoFile,*FileNames,*Offsets);
600 &ReadTagTable($BaseInfoFile,*TagList,*Exists,*IsIndirect);
601 if ($Exists == 0){ #-- no tag table available
602 return "",0;
603 }
604 if (! defined $TagList{$NodeName}){ #-- tag is not in the tag table
605 return "",0;
606 }
607 ($File,$Offset) = split(/#/,$TagList{$NodeName});
608 return $File, &max($Offset-100,0) if $File ne ""; #-- there is an
609 #-- explicite not in the tag table
610 if ($IsIndirect == 1){
611 for $i (0..$#Offsets){
612 if ($Offsets[$i] <= $Offset) { # cleaner if structure --jonh 1997.05.27
613 $FileOffset = $Offsets[$i];
614 $File = $FileNames[$i];
615 }
616 }
617 return $File, &max($Offset - $FileOffset - 100,0); #-- be safe (-100!)
618 }
619 else {
620 return "", &max($Offset - 100,0);
621 }
622 }
623
624 # FindFile: find the given file on the infopath, return full name or "".
625 # Let filenames optionally have .info suffix. Try named version first.
626 sub FindFile {
627 local($File) = @_;
628 local($Alt, $Name);
629 if ($File =~ /^(.+)\.info/) {
630 $Alt = $1;
631 } else {
632 $Alt = $File . '.info';
633 }
634 for $Name ($File, $File . '.gz', $File . '.bz2', $Alt, $Alt . '.gz', $Alt . '.bz2') {
635 for (@INFODIR) {
636 return "$_/$Name" if (-e "$_/$Name");
637 }
638 }
639 return "";
640 }
641
642 #-------------------------------------------------------
643 #
644 #------------------- MAIN -----------------------------
645 print CGI::header('-type'=>'text/html',
646 '-expires'=>60*60*24*30);
647 # use a long expiration -- it's pretty
648 # stable data. Units are seconds; this is 1 month.
649 # -- jonh 1998.05.04
650 #print "Content-type: text/html\n"; #-- Mime header for ncsa httpd 1.2
651 #print "\n";
652
653 #$PROGRAM = $0; # determine our basename
654 #$PROGRAM =~ s!.*/!!;
655 $PROGRAM = $ENV{'SCRIPT_NAME'};
656
657 $CommandLine = DeEscape($ENV{'QUERY_STRING'}); # jonh DeEscape() 1997.05.16
658 if ($CommandLine =~ /\(([^\)]+)\)(.+)/) {
659 $BaseInfoFile = &DeEscape($1);
660 $BaseInfoFile =~ s#\.\./##g; # jonh 5/20/97 -- sanitize up-references
661 $NodeName = &DeEscape($2);
662 } elsif( $CommandLine =~ /^([-_0-9a-zA-Z]+)$/) { # tolerate bare queries
663 $BaseInfoFile = &DeEscape($1);
664 $NodeName = 'Top';
665 } else {
666 $BaseInfoFile = 'dir';
667 $NodeName = 'Top';
668 }
669
670 $BaseInfoFile = "dir" if $BaseInfoFile =~ /^dir$/i;
671 $FileNameFull = &FindFile($BaseInfoFile);
672 ($File,$Offset) = &GetFileAndOffset($FileNameFull,$NodeName);
673 $File = $BaseInfoFile if $File eq "";
674 $FileNameFull = &FindFile($File);
675 &InfoNode2HTML($FileNameFull,$Offset,$NodeName,$BaseInfoFile);
676
677 exit;
678
679 ###############################################################################
680 # #
681 # Longer, more boring history #
682 # #
683 ###############################################################################
684 # ----------------------------
685 # revision 1.12
686 # date: 1995/04/05 16:58:51; author: twitham; state: Exp; lines: +1 -0
687 # Emphasize variable, function, macro, etc. definitions.
688 # ----------------------------
689 # revision 1.11
690 # date: 1995/04/05 16:37:51; author: twitham; state: Exp; lines: +5 -5
691 # Fixed bug: (file) references must be next to the *Note blah:
692 # ----------------------------
693 # revision 1.10
694 # date: 1995/04/05 15:24:25; author: twitham; state: Exp; lines: +3 -3
695 # Fixed bug: node name was matching as substring of longer node names.
696 # ----------------------------
697 # revision 1.9
698 # date: 1995/04/04 23:27:14; author: twitham; state: Exp; lines: +1 -0
699 # Fixed bug of cross ref variables being used again within a page.
700 # ----------------------------
701 # revision 1.8
702 # date: 1995/04/04 23:05:52; author: twitham; state: Exp; lines: +2 -2
703 # Added some spaces for clarity.
704 # ----------------------------
705 # revision 1.7
706 # date: 1995/04/04 23:01:02; author: twitham; state: Exp; lines: +8 -9
707 # Cleaned up the HTML.
708 # ----------------------------
709 # revision 1.6
710 # date: 1995/04/04 22:25:34; author: twitham; state: Exp; lines: +51 -26
711 # Got multi-line cross references working.
712 # ----------------------------
713 # revision 1.5
714 # date: 1995/01/19 01:43:02; author: twitham; state: Exp; lines: +27 -32
715 # Changed to use (dir)Top as default,
716 # and to make links relative to current page.
717 # ----------------------------
718 # revision 1.4
719 # date: 1995/01/17 01:23:10; author: twitham; state: Exp; lines: +24 -20
720 # Cleaned up .info filename suffix option.
721 # ----------------------------
722 # revision 1.3
723 # date: 1995/01/14 01:52:33; author: twitham; state: Exp; lines: +61 -42
724 # Lined up columns in menus, got indexes working, many other improvements.
725 # ----------------------------
726 # revision 1.2
727 # date: 1995/01/13 16:33:33; author: twitham; state: Exp; lines: +2 -10
728 # almost working at this site.
729 # ----------------------------
730 # revision 1.1
731 # date: 1995/01/13 16:33:04; author: twitham; state: Exp;
732 # Initial revision
733 #
734 # V 1.0d
735 #
736 # Minor changes from 1.0b are
737 #
738 # update to cgi specification
739 # escaping/deescaping removed
740 # error messages in english