#!/usr/bin/perl -w ## ## mkat 0.93, Andreas Freise, 12.08.2003 ## ## Perl script for multiple calls of kat (FINESSE 0.93) ## written by Gerhard Heinzel (2000) and slightly edited by myself. ## ## try example `mkat --quiet matrix.kat' ## ##################################################################### sub readinit(){ $gnucommand="gnuplot %s"; open INIFILE, "kat.ini" || warn "cannot open kat.ini"; while () { if (m/^\s*GNUCOMMAND\s*\"(.*)\"/) { $gnucommand=$1; last; } } } sub processvars() { my %vars=(); my %keys=(); my $line; my ($var,$val,$key); my @dump; my $beforecomment; my $aftercomment; #collect all variables foreach $line (@file) { if ($line =~ /^\s*(\$\w+)\s*=(.*)/) { $var=$1; $key="\\".$1; # To mask the '$' for the pattern matcher $val=$2; $val =~ s/\#.*//; $vars{$var}=$val; $keys{$var}=$key; $line = "## " . $line; } } if ($verbose) { $_=0; foreach $var (keys %vars) { print "$var=$vars{$var} "; ++$_; } print "\n" if ($_>0); } #pass again and replace foreach $line (@file) { # remove comments ($beforecomment=$line) =~ s/(\#.*)//; $aftercomment=$1; foreach $var (keys %vars) { if ($beforecomment =~ s/$keys{$var}/$vars{$var}/g) { $line = $beforecomment . $aftercomment . "## substituted $var=$vars{$var}"; } } } } sub sortkeys { my ($tag,$group,%together,%groups, @oldlist,@thislist,@templist,$thisel,$tempel); # sort tags into groups foreach $tag (sort keys %filetags) { $tag =~ m/([a-zA-Z]*)/; $group=$1; # name of group unless (defined $together{$group}) { $together{$group} = 0; } if ($tag =~ s/\+//) { # A '+' sign indicates "together" and is stripped $together{$group} = 1; } $groups{$group} .= ($tag . " "); $alltags{$tag}=1; } # print list of groups and tags if ($verbose) { foreach $group (sort keys %groups) { printf "Tag %s%s: %s\n", $group, ($together{$group})?" (together)":"", $groups{$group}; } } # make list of combinations of "together" groups foreach $group (sort keys %groups) { next unless ($together{$group}); if (defined (@tlist)) { @oldlist=@tlist; @thislist=split / /, $groups{$group}; @tlist=(); foreach $thisel (@thislist) { @templist=@oldlist; foreach $tempel(@templist){ $tempel .= ",".$thisel; } push(@tlist,@templist); } } else { @tlist = split / /, $groups{$group}; } } if (defined (@tlist)) { $ntogether=@tlist; } else { @tlist=(""); $ntogether=0; } print "Together ($ntogether combinations)=@tlist\n" if $verbose && $ntogether; # make list of combinations of "separate" groups foreach $group (sort keys %groups) { next if ($together{$group}); if (defined (@slist)) { @oldlist=@slist; @thislist=split / /, $groups{$group}; @slist=(); foreach $thisel (@thislist) { @templist=@oldlist; foreach $tempel(@templist){ $tempel .= ",".$thisel; } push(@slist,@templist); } } else { @slist = split / /, $groups{$group}; } } if (defined (@slist)) { $nseparate=@slist; } else { @slist=(""); $nseparate=0; } print "Separate ($nseparate combinations)=@slist\n" if $verbose && $nseparate; } sub gnu() { my @header; my @trailer; my $status; my @plotlines; my $plotcommand; open (GNUFILE, $gnufile) || die "Cannot open $gnufile\n"; $status=0; # extract common header and trailer from last gnufile @header=@trailer=(); while () { chomp(); #replace specific plotname by group plot name s|$filename|$plotname|; push (@header,$_) if ($status==0); $status=1 if (/^plot/); $status=3 if ($status==2); $status=2 if ($status==1 && !(/\\$/)); push (@trailer,$_) if ($status==3); } close (GNUFILE); print "header=@header\n trailer=@trailer\n" if $verbose>1; print "filename= $filename plotname=$plotname\n" if $verbose>1; @plotlines=(); $lt=0; foreach $gnufile (sort keys %gnufiles) { ++$lt; open (GNUFILE, $gnufile) || die "Cannot open $gnufile\n"; $status=0; while () { chomp(); $status=2 if ($status==1); # next line after "plot" $status=1 if (/^plot/); if ($status==2) { $notlast=s/,\\$//; # remove , and backslash s/lt\s+\d+/lt $lt/; # remove linetype s/(title\s+\".*)(\")/$1 $gnufiles{$gnufile}$2/; # insert ID push (@plotlines,$_); } $status=3 if ($status==2 && !$notlast); # last plot line } close (GNUFILE); unlink $gnufile || die "Cannot remove $gnufile\n"; } open (GNUFILE, "> $plotname.gnu") || die "Cannot open $plotname.gnu\n"; foreach (@header) { print GNUFILE "$_\n"; } $plotlines=join(",\\\n",@plotlines); print GNUFILE "$plotlines\n"; foreach (@trailer) { print GNUFILE "$_\n"; } close GNUFILE; $plotcommand=sprintf $gnucommand, "$plotname.gnu"; print "$gnucommand, $plotname.gnu, plotcommand=$plotcommand\n" if ($verbose>1); system $plotcommand; } $verbose = 1; readinit(); while ($arg = shift(@ARGV)) { # process arguments if ($arg =~ m/^-.+/){ # switches for kat push(@katarg,$arg); # are collected } else { # others push(@files,$arg); # are filenames } } # check filename arguments if (@files == 0) { die "usage: mkat [options] basename\n"; } elsif (@files > 1) { die "usage: mkat [options] basename\ only one basename is acceptable, not @files.\n"; } # get basename $basename = $files[0]; $basename =~ s|\.kat$||i; # strip trailing ".kat" or ".KAT" @fn=($basename.".kat", $basename.".KAT", $basename); # open input file open(INFILE,($infile=$fn[0])) || open(INFILE,($infile=$fn[1])) || open(INFILE,($infile=$fn[2])) || die "Cannot open any of @fn\n"; print "Reading input from $infile\n" if $verbose; # scan input file for tags and collect in a hash while () { chomp ; if (m/^\s*([a-zA-Z]*\d+\+?):/) { $filetags{$1}++; } } seek (INFILE, 0, 0); # rewind sortkeys(); @outfiles=(); #outer loop: separate foreach $sep (@slist) { @stags=split(/,/ , $sep); ($plotname =$sep) =~ s/,//; $plotname=$basename."_".$plotname; print "Plotname = $plotname:\n" if $verbose; #inner loop: together %gnufiles=(); foreach $tog (@tlist) { @ttags = split(/,/ , $tog); @tags=@stags; push (@tags,@ttags); #make list of inactive tags %disabled = %alltags; foreach (@tags) { delete $disabled{$_}; } @temp=keys %disabled; #construct output file name $id = $tog; $id =~ s/,//; $filename = $plotname.$id; $infile = $filename . ".kat"; $outfile = $filename . ".out"; $gnufile = $filename . ".gnu"; open (OUTFILE, "> $infile") || die "Cannot open $infile\n"; @tags=sort @tags; @temp=sort @temp; print (" $infile active=@tags disabled=@temp\n") if $verbose; #read input file @file=(); while ($line=) { chomp ($line); if ($ntogether>0 || $nseparate>0) { foreach $tag (@tags) { if ($line =~ s/(^\s*$tag\+?:)//) { $line .= " ## tag $1 activated"; print ("active: $1\n") if ($verbose >=2); } } foreach $tag (keys %disabled) { if ($line =~ s/(^\s*$tag\+?:)//) { $line = "## tag $1 disabled ## " . $line; print ("disabled: $1\n") if ($verbose >=2); } } } push (@file,$line); } processvars(); foreach $line (@file) { print OUTFILE "$line\n"; } seek (INFILE, 0, 0); # rewind close (OUTFILE); # call FINESSE $katoption = ($ntogether>1) ? "--perl1 " : ""; $command="./kat @katarg $katoption $infile"; # $command =~ s/^\s*//; # $command =~ s/\s*$//; $retcode = system($command); if ($retcode != 0) { die "\nFINESSE returned with error ($command)\n"; } # unlink $infile; push(@outfiles,$outfile); $gnufiles{$gnufile}=$id;; } if ($ntogether>1){ gnu(); } }