|
#!/usr/bin/perl
# This script is taken from GAP's etc/ directory. Since xgap is the only
# GAP package left using it, we make our own copy of it.
@msfiles = ();
@gdfiles = ();
$DIR = ".";
$LIB=".";
$check=0;
if ( @ARGV && $ARGV[0] =~ /-f/ ) {
open( COF, "$ARGV[1]" );
while ( $line = <COF> ) {
chomp $line;
if ( $line =~ /DIR/ ) {
@words = split /=/, $line;
$DIR = $words[1];
$DIR =~ s/[; "]//g;
print "DIR set to $DIR\n";
} elsif ( $line =~ /LIB/ ) {
@words = split /=/, $line;
$LIB = $words[1];
$LIB =~ s/[; "]//g;
print "LIB set to $LIB\n";
} elsif ( $line =~ /msfiles/ ) {
@words = split /=/, $line;
$files = $words[1];
while ( !( $line =~ /;/ ) ) { $line = <COF>; $files .= $line; }
$files =~ s/[\(\);\n" ]//g;
@msfiles = split /,/, $files;
} elsif ( $line =~ /gdfiles/ ) {
@words = split /=/, $line;
$files = $words[1];
while ( !( $line =~ /;/ ) ) { $line = <COF>; $files .= $line; }
$files =~ s/[\(\);\n" ]//g;
@gdfiles = split /,/, $files;
} elsif ( $line =~ /check/ ) {
# the manual builder should produce a file `notfound'.
$check = 1;
} elsif ( $line =~ /=/ ) {
# assignment of {{variable}} replacements
@varass = split /=/, $line;
$defaults{$varass[0]} = $varass[1];
}
}
}
sub coll_and_fam {
# cope with `DeclareCategoryFamily' and `DeclareCategoryCollection'
if ($line =~ "DeclareCategoryFamily") {
@lipa = split /\"/, $line;
$line = $lipa[1].":= NewCategory(\"".$lipa[1]."Family\");";
}
if ($line =~ "DeclareCategoryCollection") {
@lipa = split /\"/, $line;
if ($lipa[1] =~ "Collection") {
$lipa[1] =~ s/Collection//g;
$line = $lipa[1] . "CollColl := NewCategory(\"" .
$lipa[1] . "CollColl\",IsObject);";
} else {
$line = $lipa[1] . "Collection := NewCategory(\"" .
$lipa[1] . "Collection\",IsObject);";
}
}
}
sub read_table {
foreach $file ( @gdfiles ) {
$currread = ($file =~ /\.(g|tbd|tmd)/ ) ? $file : "$file.gd";
open( GDF, "$LIB/$currread") ? do {print "reading $LIB/$currread\n";
$readon=1;}
: do {print "$LIB/$currread not found.\n";
$readon=0;};
while ( ($readon) && ($line = <GDF>) ) {
if ( $line =~ /^#[CAPOFVR]/ ) {
# We look for lines of form:
# #<code> <func-name>( <args> ) . . <description>
# #<code> <var-name> . . . . . . . <description>
# where <code> is a letter in "CAPOFVR".
$nfun = 0; #no. of functions in the block
@code = (); #CAPOFVR codes of the functions
@fdec = (); #things of form: <func-name>( <args> )
#or: <var-name>
@ldes = (); #things of form: <description>
#with dots and superfluous spaces stripped out
#... which we don't currently use.
while ( $line =~ /^#([CAPOFVR])/ ) {
$code[++$nfun] = $1;
# The following piece of code is for long declarations that use several lines.
# It is assumed that such a long declaration contains "(" on the first line
# and ")" on some line below.
$des = $line;
if ( $line =~ /\(/ ) {
while ( !( $line =~ /\)/ ) ) {
($line = <GDF>) =~ s/^#[CAPOFVR]\s*/ /;
if ($line =~ /^##\s*$/) {
$des =~ m/^#([A-Z])\s*([^\(]*)/;
#Is it better to die or print an error message?
#... I opted for print error message + try to
#recover, because people don't read error
#messages ... right or wrong? - GG
#die "Closing bracket missing for ".
# "$1 definition of $2\n".
# "near line $. of $LIB/$currread\n";
print STDERR "Closing bracket missing for ",
"$1 definition of $2\n",
"near line $. of $LIB/$currread\n",
"... attempting to recover by ",
"inserting needed closing ",
"bracket.\n";
$line .= ") ";
}
$des =~ s/[%]*$/%/;
$des .= $line;
}
}
( $des =~ /#[A-Z]\s*(\w+(\s*\([^\)]*\))?)(.*)/ )
|| die "syntax error near line $. of $LIB/$currread\n";
($fdec[$nfun] = $1) =~ s/\s*\(/\(/;
($ldes[$nfun] = $3) =~ s/[.]//g;
$ldes[$nfun] =~ s/^\s+//;
$ldes[$nfun] =~ s/\s+/ /g;
#print STDERR "fdec: $fdec[$nfun], ldes: $ldes[$nfun]\n";
$line = <GDF>;
}
$code[0] = $nfun;
$fdec[0] = $nfun;
$ldes[0] = $nfun;
@words = split /\(/, $fdec[1];
$key = $words[0];
$key .= "@"; $key .= $file;
if ( ( %{ $tab{$key} } ) ) {
print "DUPLICATE DEFINITION OF $key\n";
}
@args = ();
$args[0] = $nfun;
for ($k=1; $k <= $nfun; ++$k ) {
@argsk = ();
$argsk[0] = 0;
if ( $fdec[$k] =~ /\(/ ) {
@aa = split /\(/, $fdec[$k];
$w = $aa[1];
@aa = split /\)/, $w;
$w = $aa[0];
if (!$w) { $w= " ";}
@aa = split /,/, $w;
$noa = 0;
foreach $a ( @aa ) {
++$noa;
$argsk[$noa] = $a;
}
}
$argsk[0] = $noa;
$args[$k] = [ @argsk ];
}
$expl = "";
while ( ($line = <GDF>) =~ /^#/ ) {
if ( !( $line =~ /^#T/ ) ) {
$line =~ s/^[#]*//g;
# remove two leading spaces
# Hmmm! ... This doesn't require any spaces!!
$line =~ s/^ //;
$line =~ s/^ //;
$expl .= $line;
}
}
@impl = ();
$impl[0] = $nfun;
@ipmt = ();
$ipmt[0] = $nfun;
$ww0 = "";
for ($k=1; $k <= $nfun; ++$k) {
$ww1 = $ww0;
if ( $fdec[$k] =~ /\(/ ) {
@ww = split /\(/, $fdec[$k];
$ww0 = $ww[0];
} else {
$ww0 = $fdec[$k];
}
# If the 'new' declaration is not the same as the old one, then we look for a
# new implementation line (otherwise we do not).
if ( !( $ww0 =~ /^$ww1$/ ) ) {
coll_and_fam();
while ( !( $line =~ /$ww0/ ) ) {
eof( GDF ) && die "$ww0 is declared but there ".
"is no implementation line\n... ",
"near line $. of $LIB/$currread\n";
$line = <GDF>;
coll_and_fam();
}
$defn = $line;
while ( !( $line =~ /;/ ) ) {
$line = <GDF>;
$defn .= $line;
}
}
@implk = ();
$implk[0] = 0;
$j = 0;
@words = split /,/, $defn;
foreach $w ( @words ) {
if ( !( $w =~ /\(/ ) ) {
++$implk[0];
++$j;
$implkj = "";
@wds = split / and /, $w;
foreach $v ( @wds ) {
$v =~ s/\)|\[|\]|;| |\n//g;
if ( $implkj =~ /\w/ ) {
$implkj .= ", ".$v;
} else {
$implkj .= $v;
}
}
$implk[$j] = $implkj;
}
}
$impl[$k] = [ @implk ];
@words = split /\(/, $defn;
$w = $words[0];
if ( $w =~ /:=/ ) {
@wds = split /:=/, $w;
$v = $wds[1];
} else {
$v = $words[0];
}
$ipmt[$k] = $v;
}
# Some default filling in of tester and setter (if such objects are found
# later on, they will be inserted).
@test = ();
@sett = ();
# $ntes = 0; $nset = 0;
$test[0]=0; $sett[0]=0;
$tab{$key}{test} = [ @test ];
$tab{$key}{sett} = [ @sett ];
$tab{$key}{expl} = $expl;
$tab{$key}{code} = [ @code ];
$tab{$key}{args} = [ @args ];
$tab{$key}{fdec} = [ @fdec ];
$tab{$key}{ldes} = [ @ldes ];
$tab{$key}{impl} = [ @impl ];
$tab{$key}{ipmt} = [ @ipmt ];
$tab{$key}{file} = $currread;
}
# The arrays sett and test are bags of setters and testers respectively. This
# means that they can appear in any order, it cannot be assumed that they
# correspond to the order in which the fdecs appear (for instance).
# setter and tester are now declared automatically
# if ( $line =~ /Set/ ) {
# ++$nset;
# ++$sett[0];
# @words = split /:=/, $line;
# $w = $words[0];
# $w =~ s/ //g;
# $sett[$nset] = $w;
# $tab{$key}{sett} = [ @sett ];
# } elsif ( $line =~ /Has/ ) {
# ++$ntes;
# ++$test[0];
# @words = split /:=/, $line;
# $w = $words[0];
# $w =~ s/ //g;
# $test[$ntes] = $w;
# $tab{$key}{test} = [ @test ];
# }
if ( $line =~ /#[0-9]/ ) {
@chars = split //, $line;
$hnum = $chars[1];
for ($k=2; ($c=$chars[$k]) =~ /[0-9]/; ++$k) { $hnum .= $c; }
$htxt = "";
while ( ($line = <GDF>) =~ /^#/ ) {
if ( $line =~ /##/ ) {
$line =~ s/#//g;
# remove 1 or two leading spaces
$line =~ s/^ //g;
$line =~ s/^ //g;
$htxt .= $line;
}
}
$clef = "_h".$file;
$tab{$clef}{$hnum} = $htxt;
}
}
if ( open( GIF, "$LIB/$file.gi" ) ) {
print "reading $LIB/$file.gi\n";
$currread="$file.gi";
$key = ""; $gide="";
$first = 1;
while ( $line = <GIF> ) {
if ( $line =~ /#[CAPOFVRM]/ ) {
if ( $first == 1 ) {
$first = 0;
if ( $tab{$key} ) {
$tab{$key}{gide} = $gide;
$tab{$key}{meth} = [ @meth ];
}
@words = split /\(/, $line;
$key = $words[0];
$key =~ s/#[CAPOFVRM]| //g;
$gide = "";
@mlines = ();
$nom = 0;
$insm = 0;
@meth = (0);
}
if ( $line =~ /#M/ ) {
++$nom;
$mlines[0] = $nom;
$mlines[$nom] = $line;
}
} elsif ( $first == 0 ) {
$first =1;
}
# The next lines of code handle the #M declarations that must go into the
# manual from the .gi file. We assume:
#
# * there are as many #M declarations in the header as Install(Other)Method
# lines,
# * if a method is installed by InstallOtherMethod, and it contains
# comments in the body ( #+ lines ), then the corresponding declaration
# goes into the manual.
#
# In all comment lines in the body of an InstallOtherMethod, the string
# NUMBER will be replaced by the number (integer) that reflects the position
# of this declaration in the list of all declarations.
if ( $line =~ /Install(Other|)Method/ ) {
++$insm;
$argres = "";
if ( $insm <= $nom ) {
$foundres = 0;
$hascom = 0;
$end = 0;
$occurass = 0;
while ( $end == 0 ) {
if ( $line =~ /:=/ ) { $occurass = 1; }
if ( $line =~ /^(#\+)/ ) {
$hascom = 1;
$line =~ s/^(#\+)/ /;
@words = split ' ', $line;
foreach $w ( @words ) {
if ( !($w=~/\n/) ) {$gide .= ($w." ");}
}
$gide .= "\n";
} elsif ( $foundres == 0 && $line =~ /\[/ ) {
$argres = $line;
while ( !( $line =~ /\]/ ) ) {
$line = <GIF>; $argres .= $line;
}
$met = $argres;
$met =~ s/\\\[//g;
if ( $met =~ /\[/ ) {
@words = split /\[|\]/, $met;
$met = $words[1];
$met =~ s/,|\n/ /g;
$meth[0] = $insm;
$meth[$insm] = $met;
$foundres = 1;
}
}
if ( ( $line =~ /\);/ && $occurass == 0 )
|| $line =~ /end.*\);/ ) {
$end = 1;
} else {
$line = <GIF>;
}
}
if ( $hascom == 1 ) {
if ( $tab{$key} ) {
@code = @{ $tab{$key}{code} };
@fdec = @{ $tab{$key}{fdec} };
@args = @{ $tab{$key}{args} };
@ldes = @{ $tab{$key}{ldes} };
@impl = @{ $tab{$key}{impl} };
} else {
@code = ();
@fdec = ();
@args = ();
@ldes = ();
@impl = ();
$code[0] = 0;
$tab{$key}{expl} = "";
}
$nfun = $code[0];
++$nfun;
$gide =~ s/NUMBER/$nfun/g;
$code[0] = $nfun;
$code[$nfun] = "M";
$tab{$key}{code} = [ @code ];
@words = split /\)/, $mlines[$insm];
$w = $words[0];
$w .= "\)";
$w =~ s/#M| //g;
$fdec[$nfun] = $w;
$fdec[0] = $nfun;
$tab{$key}{fdec} = [ @fdec ];
@argsk = ();
$argsk[0] = 0;
@aa = split /</, $w;
$noa = 0;
foreach $a ( @aa ) {
if ( $a =~ />/ ) {
++$noa;
$a =~ s/>| |,|\)//g;
$argsk[$noa] = $a;
}
}
$argsk[0] = $noa;
$args[0] = $nfun;
$args[$nfun] = [ @argsk ];
$tab{$key}{args} = [ @args ];
$w = $words[1];
$w =~ s/\.| |\n//g;
$ldes[0] = $nfun;
$ldes[$nfun] = $w;
$tab{$key}{ldes} = [ @ldes ];
$argres =~ s/\].*/\]/;
@implk = ();
$implk[0] = 0;
$j = 0;
@words = split /,/, $argres;
foreach $w ( @words ) {
++$implk[0];
++$j;
$implkj = "";
@wds = split / and /, $w;
foreach $v ( @wds ) {
$v =~ s/\)|\[|\]|;| |\n//g;
if ( $implkj =~ /\w/ ) {
$implkj .= ", ".$v;
} else {
$implkj .= $v;
}
}
$implk[$j] = $implkj;
}
$impl[$nfun] = [ @implk ];
$impl[0] = $nfun;
$tab{$key}{impl} = [ @impl ];
}
} else {
$meth[0] = $insm;
$foundres = 0;
while ( $foundres == 0 ) {
while ( !( $line =~ /\[/ ) ) {
$line = <GIF>;
}
$met = " ".$line;
while ( !( $line =~ /\]/ ) ) {
$line = <GIF>;
$met .= $line;
}
$met =~ s/\\\[//g;
if ( $met =~ /\[/ ) {
@words = split /\[|\]/, $met;
$met = $words[1];
$met =~ s/, |\n//g;
$meth[$insm] = $met;
$foundres = 1;
} else {
$line = <GIF>;
}
}
}
}
if ( $line =~ /^(#\+)/ ) {
$line =~ s/^(#\+)/ /;
@words = split ' ', $line;
foreach $w ( @words ) {
if ( !($w=~/\n/) ) {$gide .= ($w." ");}
}
$gide .= "\n";
}
}
if ( $tab{$key} ) {
$tab{$key}{gide} = $gide;
$tab{$key}{meth} = [ @meth ];
}
}
if ( open( GFI, "$file.g" ) ) {
$key = ""; $gdes="";
while ( $line = <GFI> ) {
if ( $tab{$key} ) { $tab{$key}{gdes} = $gdes; }
if ( $line =~ /#[CAPOFVR]/ ) {
@words = split /\(/, $line;
$key = $words[0];
$key =~ s/#[CAPOFVR]| //g;
$gdes = "";
}
if ( $line =~ /^(#\+)/ ) {
$line =~ s/^(#\+)/ /;
@words = split ' ', $line;
foreach $w ( @words ) {
if ( !($w=~/\n/) ) {$gdes .= ($w." ");}
}
$gdes .= "\n";
}
}
if ( $tab{$key} ) { $tab{$key}{gdes} = $gdes; }
}
close GDF;
}
%tab;
}
sub make_tex {
print "Reading files...\n";
%tab = {};
%tab = read_table();
foreach $msfile (@msfiles) {
open( MSK, "<$msfile.msk" )
|| die "Cannot open manual skeleton file $msfile.msk";
# if the `tex' file does already exist, make it writable
chmod 0644, "$DIR/$msfile.tex";
open( TEX, ">$DIR/$msfile.tex" )
|| die "Cannot open TeX output file $DIR/$msfile.tex.";
print "Composing the TeX file $msfile.tex\n";
print TEX "% This file was created automatically from $msfile.msk.\n",
"% DO NOT EDIT!\n";
SCANMSK: while ( $line = <MSK> ) {
# treat the {{...}} replacements
while ( $line =~ /\{\{([^}]*)\}\}/ ) {
$key = $1;
if ( $key =~ /date/ ) {
$replace=`date +"%d %B %Y"`;
} elsif ( $key =~ /year/ ) {
$replace=`date +"%Y"`;
} elsif ( $defaults{$key} ) {
$replace=$defaults{$key};
} else {
die "$key has no replacement value";
}
$line =~ s/{{$key}}/$replace/;
}
# Now deal with the `Declaration' mechanism.
# The following is the most we ever need to match:
# \Declaration{<func-name>}[<gdfile>]{<label>}!{<sub-entry>}@{<index-entry>}
# Each of [<gdfile>], {<label>}, !{<sub-entry>} and @{<index-entry>} is
# optional.
#
# [<gdfile>] tells the buildman.pe in which .gd file it should look for
# <func-name> (useful if it exists in more than one .gd file) ... it is
# also used as a sub-entry if !{<sub-entry>} is not present.
if ( $line =~ /\\Declaration/ ) {
($' =~ /\{([^}]*)\} # $1 = <func-name>
(\[([^\]]*)\])? # $3 = <gdfile> (without [])
(\{[^}]*\})? # $4 = {<label>}
(!\{[^}]*\})? # $5 = !{<sub-entry>}
(@\{[^}]*\})? # $6 = @{index-entry>}
\s*$/x )
|| die "syntax problem with line:\n$line".
"... line $. of $msfile.msk\n";
$key = $1; # <func-name>
$gdfile = (defined $3) ? $3 : ""; # <gdfile>
$label = (defined $4) ? $4 : ""; # {<label>}
$subentry = (defined $5) ? $5 : ""; # !{<sub-entry>}
$indexentry = (defined $6) ? $6 : ""; # @{index-entry>}
#print STDERR "line: $line", "key: $key\ngdfile: $gdfile\n",
# "label: $label\n", "subentry: $subentry\n",
# "indexentry: $indexentry\n";
$nokeys = 0;
%info = ();
CHKINFO:
foreach $k ( keys %tab ) { #each $k is of form: <key>@<gdfile>
#print STDERR "k: $k, key: $key\n";
if ( $k =~ /^$key\@/ ) {
#print STDERR "match ... k: $k, key: $key\n";
if ( $gdfile ne "" ) {
#print STDERR "k: $k, gdfile: $gdfile\n";
if ( $k =~ /\@$gdfile$/ ) {
#print STDERR "match ... k:$k, gdfile:$gdfile\n";
%info = %{ $tab{$k} };
$tab{$k}{used} = 1;
$nokeys++;
}
} else {
# so there was no gd file specified in the decl.
if ( $nokeys > 0 ) {
print STDERR "!!$key on line $. of $msfile.msk ",
"OCCURS IN MORE THAN ONE .gd FILE",
"\n... taking first one found.\n";
last CHKINFO;
} else {
%info = %{ $tab{$k} };
$tab{$k}{used}= 1;
$nokeys++;
}
}
}
}
if ( %info == () ) {
print STDERR
"!! key: $key NOT FOUND IN THE .gd FILES LISTED!!\n",
"line: $line", "... line $. of $msfile.msk ignored.\n";
next SCANMSK;
}
# $tab{$key}{used} = 1;
@code = @{ $info{code} };
@fdec = @{ $info{fdec} };
@ldes = @{ $info{ldes} };
for ($k=1; $k <= $fdec[0]; ++$k ) {
$fd = $fdec[$k];
# Add M to <code> if an attribute that's mutable
$mut = "";
if ( $code[$k] =~ /A/ ) {
@impl = @{ $info{impl} };
@implk = @{ $impl[$k] };
if ( $implk[$implk[0]] =~ /muta/ ) { $mut = "M"; }
}
# Add S to <code> if an attribute or property that's a setter
# Add T to <code> if an attribute or property that's a tester
# ... don't think any of this happens anymore.
$st = ""; $ts = "";
if ( $code[$k] =~ /[AP]/ ) {
($name = $fd) =~ s/(\w+)\s*\(.*/$1/;
#print STDERR "fd: $fd, name: $name\n";
foreach $s ( @{ $info{sett} } ) {
if ( $s =~ /$fd/ ) {
$st = "S";
last;
}
}
foreach $t ( @{ $info{test} } ) {
if ( $t =~ /$name/ ) {
$ts = "T";
last;
}
}
}
# A space before the bracket is *bad* for the index
$fd =~ s/\s*\(\s*/\( /;
$fd =~ s/\s*\)/ \)/;
$fd =~ s/,\s*/, /g;
#print STDERR "fd: $fd\n";
if ( $label eq "" && $indexentry ne "") {
print STDERR "\Declaration has no {<label>} but has ",
"\@{<index-entry} on\n", "line: $line",
"... line $. of $msfile.msk.\n";
# make a guess at what $label ought to be
($label = $indexentry) =~ s/[@`'<>]//g;
} elsif ( "$subentry" eq "!{}" ) {
# special case to avoid [<gdfile>] sub-entries
$subentry = "";
} elsif ( "$label$subentry" eq "" && $fd =~ /[(]/ &&
$gdfile ne "" ) {
$fd =~ /(\w*)/;
$label = "{$1![$gdfile]}"; # gapmacro.tex treats the
# !... part as <sub-entry>
$indexentry = "@\{`$1'!`[$gdfile]'}";
}
if ( $label ne "") {
print TEX "\\>`$fd'$label$subentry$indexentry";
} elsif ( $fd =~ /[(]/ ) {
print TEX "\\>$fd$subentry$indexentry";
} elsif ( $code[$k] =~ /V/ ) {
#GG : gapmacro.tex now copes with this specially
print TEX "\\>`$fd'";
} else {
print STDERR "!!Argumentless $code[$k] ",
"declaration: $fd\n";
"corresponding to line: $line",
"... line $. of $msfile.msk.\n";
print TEX "\\>`$fd'{$fd}$subentry@\{`$fd'}",
}
#was: print TEX " $code[$k]$st$ts$mut $ldes[$k]\n";
print TEX " $code[$k]$st$ts$mut\n";
}
print TEX "\n$info{expl}\n";
if ( $info{gide} ) { print TEX "$info{gide}\n"; }
if ( $info{gdes} ) { print TEX "$info{gdes}\n"; }
} elsif ( $line =~ /\\beginexample/ ) {
print TEX "\\beginexample\n";
while ( !( ($line = <MSK>) =~ /\\endexample/ ) ) {
print TEX $line;
}
print TEX "\\endexample\n";
} elsif ( $line =~ /\\(Requirements|Implications)/ ) {
@impl = @{ $info{impl} };
@args = @{ $info{args} };
print TEX "\\beginitems\n";
$lev = 1;
if ( $line =~ /\\Requirements/ ) {
print TEX "Requirements: ";
} else {
if ( $line =~ /\[.*\]/ ) {
@words = split /\[/, $line;
$w = $words[1];
@chars = split //, $w;
$lev = "";
for ($k=0; !( ($c=$chars[$k])=~/\]/ ); ++$k) {
$lev .= $c;
}
}
if ( $lev == 1 ) { print TEX "Implies: "; }
elsif ( $lev == 2 ) { print TEX "Implied by: "; }
}
if ( $lev == 1 ) {
for ($k=1; $k <= $args[0]; ++$k ) {
# If two consecutive function declarations are the same, then we don't want
# two of the same requirement lines.
@words = split /\(/, $fdec[$k];
$w = $words[0];
if ( !( $k>1 && $fdec[$k-1] =~ /^$w\(/ ) ) {
print TEX " & ";
for ($j=1; $j <= $args[$k][0]; ++$j ) {
if ( $j <= $impl[$k][0] ) {
$arg = $args[$k][$j];
$con = $impl[$k][$j];
@cons = split /, /, $con;
$fl = 1;
foreach $c ( @cons ) {
$c .= "\( $arg \)";
if ($fl==1) { $fl = 0; }
else { $c = " and ".$c; }
print TEX $c;
}
}
print TEX " ";
}
print TEX "\n";
}
}
print TEX "\\enditems\n";
}
if ( $lev == 2 ) {
@keys = keys %tab;
for ($k=1; $k <= $fdec[0]; ++$k) {
print TEX " & ";
@words = split /\(/, $fdec[$k];
$w = $words[0];
$w =~ s/ //g;
foreach $clef ( @keys ) {
if ( !( $clef =~/^_h/ ) ) {
%tb = %{ $tab{$clef} };
if ( $tb{code}[1] =~ /C/ ) {
@imp = @{ $tb{impl} };
for ($j=1; $j<=$tb{code}[0]; ++$j ) {
$im = $imp[$j][1];
if ( $im =~ /$w/ ) {
$fd = $tb{fdec}[$j];
@fds = split /\(/, $fd;
$fd = $fds[0];
print TEX "$fd~";
}
}
}
}
}
print TEX "\n";
}
print TEX "\\enditems\n";
}
} elsif ( $line =~ /\\FileHeader/ ) {
if ( $line =~ /\[.+\]/ ) {
@words = split /\[|\]/, $line;
$hnum = $words[1];
$hnum =~ s/ //g;
} else {
$hnum = "1";
}
@words = split /{|}/, $line;
$file = $words[1];
$file =~ s/ //g;
$clef = "_h".$file;
if (!$tab{$clef}) {
print "THERE DOES NOT SEEM TO BE A HEADER IN $file.gd\n";
}
print TEX $tab{$clef}{$hnum}."\n";
} elsif ( $line =~ /\\Methods/ ) {
if ( @meth = @{ $info{meth} } ) {
print TEX "\\beginitems\n";
print TEX "Methods\: ";
for ($k=1; $k<=$meth[0]; ++$k) {
print TEX " & ";
print TEX "$meth[$k]\n";
}
print TEX "\\enditems\n";
} else {
print "No methods found for $key\n";
}
} else {
print TEX $line;
}
}
# change the permission to forbid writing
chmod 0444, "$DIR/$msfile.tex";
close MSK;
}
if ( $check!=0 ) {
open( ERR, ">notfound" ) || die "Cannot open `notfound'\n";
@kk = sort(keys %tab);
foreach $key (@kk) {
if ( ! $tab{$key}{used} ) {
print ERR "$tab{$key}{file}: \t$key\n";
}
}
print "\n\nThe file `notfound' contains ",
"a list of unused declarations\n";
}
}
make_tex();
[ Dauer der Verarbeitung: 0.36 Sekunden
(vorverarbeitet)
]
|