# -*-perl-*- # # grdoc_parse # # This is the place where it is a smarty pants and actually makes the # subhtml for parsing out. # # $Id: grdoc_parse,v 1.36 1996/04/21 17:44:52 pwalker Exp $ #define some colors $pstart = ""; $pend = ""; $vstart = ""; $vend = ""; sub grdoc_parse { local ($infile) = @_[0]; local (@grdoc_regions, @tmp); $pfile = &strip_dirs($infile); print " Parsing $pfile\n" if $opt_V; open (IN, "< $infile") || die "IN: $infile: $!\n"; $in = join('',); close IN; # Strip out the regions and put them into the grdoc_regions array. if (!($in =~ m:/\*\@\@:)) { print STDERR "WARNING: $thefile contains no grdoc regions\n"; return; } @tmp = split('\@\@\*/',$in); foreach $CANDIDATE (@tmp) { $isf = 0; $isidlorelisp = 0; if ($CANDIDATE =~ m:/\*\@\@:) { $isf = ($CANDIDATE =~ m:[Cc\*]/\*\@\@:); #th modification (fortran 90 free format) $isf90 = ($CANDIDATE =~ m:!/\*\@\@:); $isidlorelisp = ($CANDIDATE =~ m:\;/\*\@\@:); $isperl = ($CANDIDATE =~ m:\#\s*/\*\@\@:); $CANDIDATE =~ s:^(.|\n)*/\*\@\@::; # Remove all the fortran idl (perl elisp...) things. $CANDIDATE =~ s:\n[Cc\*]:\n:g if $isf; #th modification (fortran 90 free format) $CANDIDATE =~ s:\n!:\n:g if $isf90; $CANDIDATE =~ s:\n[\;]+:\n:g if $isidlorelisp; $CANDIDATE =~ s:\n[\#]+:\n:g if $isperl; push (@grdoc_regions, $CANDIDATE); } } $regioncount = $#grdoc_regions + 1; # OK, great. So now step through the regions, see if we are # a file or routine, and handle appropriately. # # Note the additional code here. Check further down the stact # to look for regions which do not match file, header, or routine. while ($REGION = shift(@grdoc_regions)) { while ($morestuff = shift(@grdoc_regions)) { if ($morestuff =~ m:@(file|header|routine):) { @grdoc_regions = ($morestuff, @grdoc_regions); last; } else { $REGION = "$REGION\n$morestuff"; } } if ($REGION =~ m:@(file|header):i) { &parse_file($REGION); } elsif ($REGION =~ m:\@routine:i) { &parse_routine($REGION); } else { print "INTERNAL ERROR: Neither routine nor file/header\n"; } } } sub parse_file { local ($region) = @_[0]; # Whole idea here is we pick off things as we process them, leaving # other stuff around in region to still be processed while writing # the output file. # OK, start by figuring out what my file is. $isheader = 0; ($region, $file) = &get_keyword($region,"file"); if ($file =~ m:^$:) { ($region, $file) = &get_keyword($region, "header"); $isheader = 1; } $file =~ s:[\n\s]::g; if (!($mysubdir{$file} || $rootfiles{$file})) { print STDERR "WARNING: No Sub Dir for :$file:\n"; print STDERR join(" ",keys %rootfiles); return; } else { $msd = $mysubdir{$file}; } $urlfile = $file; $urlfile =~ s:\.:_:g; $outname = "$opt_o/$msd/${urlfile}_File_Doc.html"; open (OUT, ">$outname") || die "OUT $outname: $!\n"; print " P: CREATED $outname\n" if $opt_V; if ($isheader) { &html_head("\@header: $file\n"); print OUT "

\@header: "; } else { &html_head("\@file: $file\n"); print OUT "

\@file: "; } print OUT "$file

\n"; &navigation($dadots); print OUT "
\n"; &localnav($file); print OUT &indent("$totallines{$file} Lines ($totalgrdlines{$file} grdoc lines)"); print OUT "

\n"; print OUT "\n"; $region = &parse_top_common_stuff($region, $file); $didrouts = 0; foreach $ROUTINE (sort cialph keys %routine_home) { if ($routine_home{$ROUTINE} =~ m/^$file$/) { if (!$didrouts) { $didrouts = 1; print OUT "\n\n"; print OUT "
Contains Routines\n"; print OUT "

"; print OUT "\n"; } print OUT "\n"; } } print OUT "
"; &localnav($ROUTINE, "brief"); print OUT "
\n\n" if ($didrouts); $region = &parse_bot_common_stuff($region); &do_leftovers($region); print OUT "\n\n"; print OUT "
"; &navigation($dadots); if ($isheader) { &html_foot("\@header: $file\n"); } else { &html_foot("\@file: $file\n"); } } sub parse_routine { local ($region) = @_[0]; # Whole idea here is we pick off things as we process them, leaving # other stuff around in region to still be processed while writing # the output file. # OK, start by figuring out what my file is. ($region, $routine) = &get_keyword($region,"routine"); $routine =~ s:[\n\s]::g; if (!($mysubdir{$routine_home{$routine}} || $rootfiles{$routine_home{$routine}} )) { print STDERR "WARNING: No Sub Dir for $routine\n"; return; } $msd = $mysubdir{$routine_home{$routine}}; $urlfile = $routine; $urlfile =~ s:\.:_:g; $outname = "$opt_o/$msd/${urlfile}_Routine_Doc.html"; # Make the file header open (OUT, ">$outname") || die "OUT 2 $outname: $!\n"; print " P: CREATED $outname\n" if $opt_V; &html_head("\@routine: $routine\n"); print OUT "

\@routine: $routine

\n"; $myfile = $routine_home{$routine}; $myfileurl = $myfile; $myfileurl =~ s:\.:_:g; $myfileurl = "${myfileurl}_Rich_Doc.html"; &navigation(); print OUT "
\n"; &localnav($routine); print OUT "

\n"; # Region for inclusion in Rich Docs print OUT "\n"; $region = &parse_top_common_stuff($region, $routine); $region = &parse_bot_common_stuff($region, $routine); # Check for Entry Points ($region, $iste, $teval) = &get_boolean($region, "treeentry"); $routineTreeEntry{$routine} = "GRDOCENTRY$teval" if $iste; &do_leftovers($region); print OUT "\n\n"; # And a footer print OUT "


"; &navigation($dadots); &html_foot("\@routine: $routine\n"); } sub parse_top_common_stuff { local ($region, $myname) = @_; local ($version, $author, $date, $descr, $deschead); local ($stencil, $defines); ($region, $version) = &get_keyword($region, "version"); ($region, $author) = &get_keyword($region, "author"); ($region, $date) = &get_keyword($region, "date"); ($region, $desc, $deschead) = &get_container($region, "desc"); ($region, $stencil) = &get_keyword($region, "stencil"); ($region, $defines) = &get_keyword($region, "defines"); ($region, $rettype) = &get_keyword($region, "returntype"); ($region, $retdesc, $retdeschead) = &get_container($region, "returndesc"); $test = "$version$date$author"; if (!($test =~ m:^$:)) { print OUT ""; &no_html_row("Version",$version); &no_html_row("Author",$author, $isfile); &no_html_row("Date",$date); print OUT "
\n"; } if ($desc =~ m:\S:) { $dt = "Description"; $dt = "$dt: $deschead" if (!($deschead =~ m:^\s*$:)); print OUT "
$dt
\n"; print OUT &indent($desc); } if ($rettype =~ m:\S:) { $dt = "Return Type: $rettype"; $dt = "$dt: $retdeschead" if (!($deschead =~ m:^\s*$:)); print OUT "
$dt
\n"; if ($retdesc =~ m:\S:) { print OUT &indent($retdesc); } } if ($routine_f_sub{$myname}) { print OUT "
Fortran Prototype
\n"; print OUT "
$routine_f_sub{$myname}
\n"; } if ($defines =~ m:\S:) { print OUT "
Defines
\n"; print OUT &indent($defines); } if ($stencil =~ m:\S:) { print OUT "
Stencil
\n"; print OUT &indent($stencil); } $region = &do_vars($region, $myname); $region = &do_pars($region, $myname); return ($region); } sub parse_bot_common_stuff { local ($region, $myname) = @_; local ($comm, $commhead); $region = &do_history($region); # Note we need to do it this way so the seealso doesn't munge the # comment ($region, $comm, $commhead) = &get_container($region, "comment"); $region = &do_seealso($region, $myname); if ($comm =~ m:\S:) { $ct = "Comment"; $ct = "$ct: $commhead" if (!($commhead =~ m:^$:)); print OUT "
$ct
\n"; print OUT &indent($comm); } return ($region); } sub no_html_row { local($tag, $value) = @_; $value = &html_safe($value); $value =~ s:\n::; if (!($value =~ m:^\s*$:)) { print OUT "$tag"; print OUT "$value\n"; } } sub get_container { local ($region, $kw) = @_; local ($value, $head); local ($firstbit, @rest, $lastbit, $pv, $ph); $value = ""; $head = ""; $pv = ""; $ph = ""; if (!($region =~ m:\@$kw:i)) { $head = ""; $value = ""; return ($region, $value, $head); } while ($region =~ m:\@$kw:i) { ($firstbit, @rest) = split("\@end$kw", $region); $lastbit = join("\@end$kw", @rest);; $firstbit =~ s:\@$kw(.*)\n((.|\n)*)$::i; $pv = $2; $ph = $1; $value .= "

" if (($value =~ m:\S:) && ($kw =~ m:^(comment|desc):)); $value .= $pv; $head = $ph if ($head =~ m:^$:); $region = "$firstbit$lastbit"; last unless ($kw =~ /^(comment|desc)/i); } # resolve XRefs in $value $value = &resolve_XRefs($value, "norich"); # Handle TeX in $value if ($opt_T) { while ($value =~ m:(\$+[^\$]+\$+):) { $origtex = $1; if (!($origtex =~ m:^\$(Id|Log):)) { $newtex = &tex_to_html($origtex); $value =~ s:(\$+[^\$]+\$+):GRDOCTEXREPLACETHIS:; $value =~ s:GRDOCTEXREPLACETHIS:$newtex:; } else { print "Rejecting $origtex for TeX conversion!\n" if ($opt_V); $origtex =~ s:\$::g; $value =~ s:(\$+[^\$]+\$+):GRDOCTEXREPLACETHIS:; $value =~ s:GRDOCTEXREPLACETHIS:$origtex:; } } } # Make the rest of the region again. return ($region, $value, $head); } sub get_boolean { local ($region, $kw) = @_; local ($value, $gotit); $value = ""; $gotit = 0; if ($region =~ m:\@$kw:) { $gotit = 1; $region =~ s:(\@$kw)([^\@]*)::; $value = $2; $value =~ s:\n::g; $value =~ s:^\s+::g; $value =~ s:\s+$::g; } return ($region, $gotit, $value); } sub get_keyword { local ($region, $kw) = @_; local ($value); if ($region =~ m:\@$kw:i) { $region =~ s:\@$kw([^\@]+)::; $value = $1; } else { $value = ""; } return ($region, $value); } sub resolve_XRefs { local ($value, $norich) = @_; local ($xref, $item, $kw, $msd, $murlf, $isroutine, $punct); while ($value =~ m:@(see\S+|calls|calledby)\s+(\S+):i) { $kw = $1; $item = $2; $isroutine = 0; ($item, $punct) = &de_punctualize($item); if ($mysubdir{$item}) { $msd = $mysubdir{$item}; $murlf = $item; } elsif ($rootfiles{$item}) { $msd = ""; $murlf = $item; } elsif ($routine_home{$item}) { $isroutine = 1; if ($norich) { $murlf = $item; } else { $murlf = $routine_home{$item}; } $msd = $mysubdir{$routine_home{$item}}; } else { if (!($item =~ m:^$:)) { print "WARNING: Unresolved XRef to >>$item<<\n"; $xref = "$item$punct"; } $value =~ s:@(see\S+|calls|calledby)(\s+)(\S+):$xref:i; next; } $msd .= "/"; $murlf =~ s:\.:_:g; if ($norich) { if ($isroutine) { $murlf = "${murlf}_Routine_Doc.html"; } else { $murlf = "${murlf}_File_Doc.html"; } } else { $murlf = "${murlf}_Rich_Doc.html"; } $murlf = "$msd/$murlf"; $murlf =~ s:[/]+:/:g; $murlf =~ s:^/::; $murlf = "$opt_t/$murlf"; $xref = "$item$punct"; $value =~ s:@(see\S+|calls|calledby)(\s+)(\S+):$xref:i } return $value; } # Ahh, the joys of perl 1;