summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorallen <allen@17b73243-c579-4c4c-a9d2-2d5706c11dac>2002-04-19 20:37:24 +0000
committerallen <allen@17b73243-c579-4c4c-a9d2-2d5706c11dac>2002-04-19 20:37:24 +0000
commit9e1b474c14866d13c20cd77ae71b0badd63846a0 (patch)
treef169e62196211a33246d756132451cd8ac5baefc /lib
parent1f4495ae416afa3218575056fd72d8dac55bef18 (diff)
New version of script for creating ThornGuide from Ian Kelley
git-svn-id: http://svn.cactuscode.org/flesh/trunk@2730 17b73243-c579-4c4c-a9d2-2d5706c11dac
Diffstat (limited to 'lib')
-rw-r--r--lib/sbin/ParamLatex.pl810
-rwxr-xr-xlib/sbin/SchedLatex.pl540
-rw-r--r--lib/sbin/ThornGuide.pl123
-rw-r--r--lib/sbin/ThornList.pl111
-rw-r--r--lib/sbin/ThornUtils.pm703
5 files changed, 1752 insertions, 535 deletions
diff --git a/lib/sbin/ParamLatex.pl b/lib/sbin/ParamLatex.pl
index 8531cfc7..8f056744 100644
--- a/lib/sbin/ParamLatex.pl
+++ b/lib/sbin/ParamLatex.pl
@@ -1,559 +1,417 @@
#!/usr/bin/perl -s
+# here we say to play it safe and not let variables pop up from anywhere, except for
+# the following variables in the 'use vars' statement, that can be passed in from
+# the command.
+use strict;
+use vars qw($h $help $cctk_home $thornlist $outdir $verbose $debug $arrangements_dir $document_type);
+
#########################
# ->> ParamLatex.pl <<- #
#########################################################################
-# #
# standard help function #
-# #
#########################################################################
-if ($h || $help) {
- print "--> ParamLatex.pl <--\n";
- print "Options:\n";
- print "\t-th= : (semi opt) thorn to process\n";
- print "\t-arr= : (semi opt) arrangement to process\n";
- print "\t-processall : (opt) process all arrangements\n";
- print "\t-directory= : (opt) dir. of arrangements (default arrangements/)\n";
- print "\t-thornlist= : (opt) list specific thorns to process\n";
- print "\t-dump : (opt) dumps output to screen, not in Latex\n";
- print "\t-scope= : (opt) restricted/global/private/shares/all (default all)\n";
- print "\t-sort= : (opt) by: scope, type, name (default name)\n";
- print "\t\t-reverse : (opt) reverse whatever the sorting is\n";
- print "\t-grouping= : (opt) file ouput grouping scope (bythorn/byarrangement/all)\n";
- print "\t-document : (opt) creates a TeX document, not just a table\n";
- print "\t-width= : (opt) fixed width of table (default 160mm)\n";
- print "\t-spacing= : (opt) vertical spacing between elements (default 6mm)\n";
- print "\t-outdir= : (opt) directory to dump output files, default is .\n";
- print "\t-section : (opt) makes this a section of a greater document\n";
- print "\t-h/-help : (opt) this screen\n";
- print "Example:\n";
- print "\tperl -s /lib/sbin/ParamLatex.pl -outfile=mytable.tex -width=8.5cm\n";
- exit 0;
+if ($h || $help)
+{
+print <<EOC;
+This program will take as input a thornlist, and outputs a latex table that contains the information in the thorns' param.ccl file(s). This latex table can then be used as a stand-alone document, or as a section of a large "ThornGuide"
+
+-cctk_home= : root directory of Cactus
+-arrangements_dir= : arrangements directory
+-thornlist= : thornlist to process
+-outdir= : where to place resulting output files
+-document_type= : is this a self containted 'document' or 'section'
+-verbose : verbose output
+-debug : (=1 is debug, >1 prints more info)
+-h | -help : this screen
+EOC
+
+exit 0;
}
-#########################################################################
-# #
-# This program will take as input a thorn, and output a latex table #
-# that contains the information in that thorns param.ccl file. #
-# #
-#########################################################################
+#/*@@
+# @file ParamLatex.pl
+# @date Sun Mar 3 19:05:41 CET 2002
+# @author Ian Kelley
+# @desc
+# This program will take as input a thornlist, and outputs a latex table
+# that contains the information in the thorns' param.ccl file(s). This latex
+# table can then be used as a stand-alone document, or as a section of a large
+# "ThornGuide"
+# @enddesc
+# @version
+#@@*/
+
+# setup the cctk_home, if it doesn't exist, we leave it blank
+$cctk_home .= '/' if (($cctk_home !~ /\/$/) && (defined $cctk_home));
+
+# set up the sbin dir, tacking cctk_home on the front
+my $sbin_dir = "${cctk_home}lib/sbin";
##############
# REQUIRE(S) #
##############
-$sbin_dir = "lib/sbin";
+# common procedures used to create the thornguide(s)
+require "$sbin_dir/ThornUtils.pm";
+
+# for use of create_parametere_database
require "$sbin_dir/parameter_parser.pl";
require "$sbin_dir/CSTUtils.pl";
-###########################
-# COMMAND LINE VAR. CHECK #
-###########################
+# for reading of the thornlist routine: %thorns = &ReadThornlist($thornlist)
+require "$sbin_dir/MakeUtils.pl";
-if (! $width) {$width="160mm";}
-if (! $sort) {$sort="name";}
-if (! $spacing) {$spacing="6mm";}
-if (((! $th) && (! $arr)) && (! defined $processall)) {
- die "\nNo -th= or -arr= (or -processall) specified, nothing to process!\n";
-}
-if (! $directory) {$directory="arrangements/";}
-if (! $grouping) {$grouping="bythorn";}
+#####################
+# INITIAL VARIABLES #
+#####################
+my $start_directory = `pwd`;
+chomp ($start_directory);
-##################
-# INITIALIZATION #
-##################
+my $TABLE_WIDTH = "160";
+my $MAX_VAR_LENGTH = "20";
-@valid_types = qw(restricted global private shared);
+# set some variables in ThornUtils(.pm) namespace
+$ThornUtils::cctk_home = $cctk_home;
+$ThornUtils::start_directory = $start_directory;
+$ThornUtils::verbose = $verbose;
+$ThornUtils::debug = $debug;
-$start_directory=`pwd`;
-chomp($start_directory);
+# Just declare stuff in a common place, with some brief descriptions
-if (! $outdir) {
- $outdir = "./";
-} else {
- if ($outdir =~ /^\//) {
- if (! -d "$outdir") {
- mkdir($outdir, 0755);
- print STDERR "\nCreating directory: $outdir" if ($verbose);
- }
- } else {
- if (! -d "$start_directory/$outdir") {
- mkdir("$start_directory/$outdir", 0755);
- print STDERR "\nCreating directory: $start_directory/$outdir" if ($verbose);
- }
- }
- if (! ($outdir =~ /\/$/)) {
- $outdir .= "/";
- }
-}
+my %thorns; # what we add the output of &ReadParameterDatabase to, used for
+ # /-> used temporary when calling &ReadThornlist, which returns a hash
+my %arrangements_database; # |--> simplicity of organization.
+my %parameter_database; # what we get as a return value from &create_parameter_database
+my %pathsToThorns; # hash of thorn names and absolute paths to their directories
+my %arrangements; # hash of arrangements, with links to lists of thorns
+my @listOfThorns; # a list of thorns, made by reading/creating a thornlist
-print STDERR "\nOutput directory is: $outdir" if ($verbose);
+# set some defaults
+$document_type ||= 'section';
-if (defined $thornlist) {
- &Read_ThornList($thornlist);
- }
+#####################
+# END: DECLARATIONS #
+#####################
-#################################################
-# FIND THORN(S)/ARRANGEMENT(S) AND CREATE LATEX #
-#################################################
+# get/setup the output directory and the arrangements directory
+$outdir = ThornUtils::SetupOutputDirectory($outdir);
+$arrangements_dir = ThornUtils::GetArrangementsDir($arrangements_dir);
-@arrangements = &Find_Directories($directory);
+# determine thornlist, create one if one doesn't exist
+if (defined $thornlist) {
+ # provided by MakeUtils.pl, returns a hash with a list of the thorns in our thornlist
+ %thorns = &ReadThornlist($thornlist);
+ @listOfThorns = keys %thorns;
+} else {
+ # we don't have a thornlist, go find all thorns in arrangements directory
+ @listOfThorns = ThornUtils::CreateThornlist($arrangements_dir);
+}
-&StartDocument("MasterTable") if ((! $dump) && ($grouping eq "all"));
+# this will return us a hash with keys as thorn names, and values as absolute paths to the
+# thorn's directory param.ccl can be located in that path.
+# We need this information to create a parameter database using create_parameter_database
+#
+# We are not doing ''one'' call to parameter_database as we easily could, because there is NO WAY
+# (currently) to distinguish between two identical thorns in different arrangements. So we
+# would get stuff from Alphathorns/IOHDF5 in CactusBase/IOHDF5, or/and visa-versa.
+ThornUtils::ClassifyThorns(\%arrangements, @listOfThorns);
+
+# lets go through, one arrangement at a time
+foreach my $arrangement (keys %arrangements)
+{
+ print "\n$arrangement" if ($debug);
+ # now each thorn in the given arrangement
+ foreach my $thorn (@{$arrangements{$arrangement}})
+ {
+ print "\n\t$thorn" if ($debug);
-foreach $arrangement (sort @arrangements) {
- @thorns = &Find_Directories($directory . $arrangement);
+ # get the path for this individual thorn
+ %pathsToThorns = ThornUtils::GetThornPaths(["$arrangement/$thorn"], $arrangements_dir, "param.ccl");
- &StartDocument($arrangement) if ((! $dump) && ($grouping eq "byarrangement"));
- THORN: foreach $thorn (@thorns)
- {
- # print STDERR "\nTHORN: $arrangement $thorn";
- if (($processall) || (($thorn eq $th) || ($arr eq $arrangement)))
- {
-
- ## do not create a file for this thorn if it is not in the THORNLIST (if one is specified)
- if ((defined $thornlist) && (! defined $thornlist{"$arrangement/$thorn"})) {
- next THORN;
- }
-
- if (-e "$directory$arrangement/${thorn}/param.ccl")
- {
- &StartDocument($thorn, $arrangement) if ((! $dump) && ($grouping eq "bythorn"));
-
- $$thorn{$thorn} = "${directory}${arrangement}/${thorn}";
- %parameter_database = &create_parameter_database(%$thorn);
- &ReadLatexDatabase(%parameter_database);
- &FormatTable;
-
- &EndDocument if ((! $dump) && ($grouping eq "bythorn"));
-
- ###################################################
- # reset the variables in case they are used again #
- undef %alreadydone;
-
- foreach $group_name (@valid_types) {
-# print STDERR "\n\t\t-->$group_name";
- foreach $table (@$group_name) {
- # print STDERR "[$table]";
- undef %$table;
- }
- }
- # END of reset #
- ################
- }
- }
+ # now we create a parameter database (for one thorn), using the function
+ # &create_parameter_database which is provided by 'parameter_parser.pl'
+ %parameter_database = &create_parameter_database(%pathsToThorns);
+
+ # Go split up the information we have recieved (again, for just this one thorn)
+ $arrangements_database{$arrangement}->{$thorn} = &ReadParameterDatabase(\%parameter_database);
}
- &EndDocument if ((! $dump) && ($grouping eq "byarrangement"));
}
-&EndDocument if ((! $dump) && ($grouping eq "all"));
+# just dump out the data-structure if we are in debug mode, don't create any files
+if ($debug) {
+ ThornUtils::Dump(\%arrangements_database);
+ print "\n";
+ exit 0;
+} else {
+ ThornUtils::ProcessAllArrangements(\%arrangements_database);
+}
-print "\n" if ($verbose);
-#########################################################################
-# END OF MAIN SECTION OF THE PROGRAM #
-#########################################################################
+print "\nFinished.\n";
+#############
+# END: MAIN #
+#############
#########################################################################
# BEGINNING OF SUB-ROUTINES #
#########################################################################
-#########################################################################
-# ReadLatexDataBase #
-# Calls parameter_parser.pl, which will read in the param.ccl file #
-# from a single thorn and return all data as a %hash table, which we #
-# will then parse to put into our own %hash tables named according to #
-# the variable names. #
-# #
-# %(variable_name) : any number of hashes created with their names #
-# being the variable names, they then have $keys #
-# (descriptions) with $values (well, values) #
-# (e.g.) $name{"default"} = "Cactus"; #
-# @global \ #
-# @restricted \ -> arrays containing the names of the relative #
-# @private / hashes that are contained within their scopes #
-# @shared / (masterlist contained in @valid_types) #
-#########################################################################
-sub ReadLatexDatabase
+#/*@@
+# @routine ReadParameterDatabase
+# @date Sun Mar 3 01:54:37 CET 2002
+# @author Ian Kelley
+# @desc
+# Hops through the parameter_database we got from &create_paramater_database, and trys
+# to classify things in a complex data-structure (hash of hashes of (hashes/arrays)) or
+# something like that.
+# &ReadParameterDatabase(\%parameter_database);
+#
+# It then returns this data-structure, which can then be better (and cleaner) accessed
+# when creating the latex page (as all the parsing was done here)
+#
+# Below are some examples of how to access data in the newly created structure:
+#
+# [print out all the ''variables'']
+# print "\nProgram variables:";
+# foreach my $variable (keys %{$thorn{"variables"}}) {
+# print "\n $variable";
+# foreach my $key (keys %{$thorn{"variables"}{$variable}}) {
+# print "\n $key = $thorn{\"variables\"}->{$variable}->{$key}";
+# }
+# }
+#
+# [print out which variables are shared (an array)]
+# print "\nShared group variables: ";
+# foreach (@{$thorn{"groups"}{"shares"}}) {
+# print "\n $_";
+# }
+#
+# NOTE: Naturally, you will have to take into account that the returned hash (%thorn) may be
+# part of a greater data-structure, so you may have to do something like:
+# foreach (keys %{$thorns{"CactusWave"}{"WaveToyC"}{"variables"}}) {
+# @enddesc
+# @version
+#@@*/
+sub ReadParameterDatabase
{
- my(%parameter_database) = @_;
- my($field);
- my(@temp) = ();
- my($temp) = "";
- my($name) = "";
-
- #######################
- # reinitialize values #
- foreach $typ (@valid_types) {
- while (defined pop(@$typ)) {pop @$typ;}
- }
- # where is global type???
-
- foreach $field (sort keys %parameter_database)
- {
- print STDERR "\n$field --> $parameter_database{$field}" if ($verbose);
-
- &Clean;
- #################
- # ADD TO SCOPES #
- #################
- if ($field =~ /\sPRIVATE\s/) {
- @private = split/ /, $parameter_database{$field};
- } elsif ($field =~ /\sRESTRICTED\s/) {
- @restricted = split/ /, $parameter_database{$field};
- } elsif ($field =~ /\sSHARES\s+(\w+)\s+var/) {
- @temp = split/ /, $parameter_database{$field};
-
- foreach $var (@temp) {
- $var=~ tr/A-Z/a-z/;
- $$var{"shared"}=$1;
- }
- push @shared, @temp;
- } else {
- #####################
- # ADD VARIABLE HASH #
- #####################
+ my (%parameterDatabase) = %{$_[0]};
- if ($field =~ /(.*?)\s(.*?)\s(.*)/) {
- $name = $2;
- $field_des=$3;
- $temp = $1;
- } else {
- #print STDERR "\n\nTHROWNING AWAY: $field $paramater_database{$field}";
- }
+ my %thorn;
- $name =~ tr/A-Z/a-z/;
- $$name{$field_des}=$parameter_database{$field};
-
- $$name{"name"} = $name;
+ # only deals with one thorn at a time, as that is currently the nature of this program
+ foreach (sort keys %parameterDatabase)
+ {
+ print "\n--> [$_] = [$parameterDatabase{$_}]" if ($debug>1);
- $$name{"thorn"} = $temp;
- }
- } #-- foreach
- print "\n";
+ # save he original key, as we will make it all lower case later
+ # and need the original for hash keys
+ my $old_key = $_;
- ################################
- # ADD ELEMENT $$table{"scope"} #
- ################################
+ # just in case they have declared it, but put nothing in it.
+ # if they did, don't waste our time parsing it.
+ next if (! $parameterDatabase{$old_key} =~ /\w/);
- foreach $group_name (@valid_types)
- {
- foreach $table (@$group_name)
+ # drop the keys to lower-case, as they are all upper-case
+ tr/A-Z/a-z/;
+
+ # see if we are grabbing variable lists
+ # (by scopes: global, private, restricted, shared, ...)
+ if (/^(.*?)\s+(.*?)\s+(.*?)\s*?variables$/)
{
- # print STDERR "\n\t\t!!!!!!!! $table";
- $table =~ tr/A-Z/a-z/;
- # print STDERR "\n$table";
- $$table{"scope"} = $group_name;
- if ($$table{"shared"}) {
- $$table{"scope"} .= " from " . $$table{"shared"};
- }
- }
-
- }
- return $name;
-} ## END :ReadLatexDatabase:
+ my @vars = split/\s+/, ThornUtils::ToLower($parameterDatabase{$old_key});
-#########################################################################
-# FormatTable #
-# Primary function to be used to format the LaTex output to whatever #
-# sorting or grouping mechanism specified by the user. #
-#########################################################################
-sub FormatTable {
- # sort: scope, type, name
- my (@all);
- while (defined pop(@all)) {pop @all;}
-
- if ($sort eq "scope") {
- if ((defined $scope) && ($scope ne "all")) { # only one scope to output
- if ($dump) {
- &Dump(sort @$scope);
- } else {
- &CreateLatexTable(sort @$scope);
- }
- } else {
- foreach $type (@valid_types) {
- if ($dump) {
- &Dump(sort @$type);
- } else {
- &CreateLatexTable(sort @$type);
- }
+ # remember the scopes for each variable
+ foreach (@vars) {
+ $thorn{"variables"}->{$_}->{"scope"} = $2 eq "shares" ? "shared from ". ThornUtils::ToUpper($3) : $2;
}
- }
- } else {
- if ((defined $scope) && ($scope ne "all")) { # only print one scope
- @all = @$scope;
- } else { # print all scopes
- foreach $type (@valid_types) {
- push @all, @$type;
- }
- }
- if ($sort eq "name") {
- @all = sort @all;
- } else {
- @all = sort SortByType @all;
+ @{$thorn{"groups"}->{$2}} = @vars;
+ next;
}
- if ($dump) {
- &Dump(@all);
- } else {
- &CreateLatexTable(@all);
- }
- }
+ # see if we can parse out some information from the keys
+ # if we cannot, drop a warning and continue
+ if (! /^(.*?)\s(.*?)\s(.*)$/) {
+ print STDERR "\nConfused: [$_] = [$parameterDatabase{$old_key}]" if ($verbose);
+ next;
+ }
- print "\n" if ($verbose || $dump);
-} ## END :FormatTable:
+ # let the thorn hash explicitly know the thorn name
+ $thorn{"thorn name"} = $1;
-#########################################################################
-# CreateLatexTable #
-# Intermediary function in the process of creating a LaTex table that#
-# loops through an array (of name passed in) and outputs LaTex in #
-# THE ORDER SPECIFIED IN THAT ARRAY. So, there you have it, the #
-# foundation for sorting. :) #
-#########################################################################
-sub CreateLatexTable {
- my (@cur_group) = @_;
+ # add the new variable in the form of:
+ # $thorn{"variables"}->{"initialize_memory"}->{"default"} = "none";
+ $thorn{"variables"}->{$2}->{$3} = $parameterDatabase{$old_key};
+ } # end: foreach %parameterDatabase
- foreach $table (@cur_group)
- {
- $table =~ tr/A-Z/a-z/;
-
- if (lc($$table{"thorn"}) eq lc($thorn)) {
- if (! defined $alreadydone{"$thorn$table"}) {
- &LatexTableElement;
- $alreadydone{"$thorn$table"} = 1; # to try to only print each once.
- }
- }
- }
-} ## END :CreateLatexTable:
-
-
-#########################################################################
-# StartDocument #
-# Opens the file OUT with the name sent in to this function a .tex #
-# extension in the working directory for output of LaTeX code. #
-# #
-# If specified with the -document flag on the command line, this #
-# function will also print basic LaTeX commands to start a document #
-#########################################################################
-sub StartDocument {
- my ($group_name) = shift;
- my ($arrangement) = shift;
-
- die "Cannot group tables for output, internal error in &StartDocument" if (! defined $group_name);
-
- chdir ($start_directory);
- open(OUT, ">$outdir${arrangement}_${group_name}_par.tex") || die "cannot open $outdir${group_name}_par.tex for output: $!";
- $oldfilehandle = select OUT;
-
- if ($document) {
- print "\\documentclass[12pt,a4paper]\{article\} \n";
- print "\\begin\{document\} \n\n";
- } elsif ($section) {
- $group_name =~ s/\_/\\\_/g;
- print "\\section{Parameters} \n\n";
- }
+ # return a reference to the newly created hash
+ return \%thorn;
+}
-} ## :StartDocument:
+#/*@@
+# @routine ProcessOneThorn
+# @date Sun Mar 3 01:54:37 CET 2002
+# @author Ian Kelley
+# @desc
+#
+# @enddesc
+# @version
+#@@*/
+sub ProcessOneThorn
+{
+ # get the thorn hash
+ my (%thorn) = %{$_[0]};
+ my $arrangement = $_[1];
+ my $thorn = $_[2];
+ my $latex_output = "";
+
+ my $ofh = ThornUtils::StartDocument("param", $thorn, $outdir, $arrangement, "Parameters", $document_type);
-#########################################################################
-# EndDocument #
-# Ends a LaTeX document (if -document) specified, and closes the OUT #
-# file, which is used to write the LaTeX table to. #
-#########################################################################
-sub EndDocument {
- if ($document) {
- print "\\end\{document\} \n";
+ # go get the latex for setting the width of the columns based on the longest variable we have
+ # (contained in the vaor $paragraph_len
+ if (defined $thorn{"variables"}) {
+ $latex_output = ThornUtils::SetWidth($TABLE_WIDTH, ThornUtils::CleanForLatex(FindMaxVarLen($thorn{"variables"})));
}
- close OUT;
- select $oldfilehandle;
-} ## :EndDocument:
-
-#########################################################################
-# LatexTableElement #
-# Takes whatever table element is currently reffered to by $table #
-# and prints it out into a LaTeX table. Only nifty things it curr. #
-# does is NOT print ranges for BOOLEAN and SHARED elements. #
-#########################################################################
-sub LatexTableElement {
- $table =~ tr/A-Z/a-z/;
- my ($name) = $table;
- my ($description) = $$table{"description"};
- my ($default) = $$table{"default"};
- $default =~ s/\_/\\\_/g;
- $default =~ s/%/\\%/g;
-
- $name =~ s/\_/\\\_/g;
- $description =~ s/\_/\\\_/g;
-
- # new addition 4/2001
- $description =~ s/\^/\\\^/g;
-
- print "$table{\"thorn\"}";
-
- $parawidth = $width;
- $parawidth =~ /(\d+)(.*)/;
-
- $parawidth = ($1 - 35) . $2;
-
- if (! (($$table{"description"} !~ /\w/) && (defined $$table{"shared"}))) {
- print "\\begin\{tabular*\}\{$width\}\{|c|c|c|\@\{\\extracolsep\{\\fill\}\}r|\} \\hline \n";
- print "\{\\bf Name\} & \{\\bf Default\} & \{\\bf Scope\} & \{\\bf Type\} \\\\ \n";
- print "\\hline \n";
- print "$name & $default & $$table{\"scope\"} & $$table{\"type\"} \\\\ \n";
- print "\\hline\\hline\n";
- print "\\multicolumn\{4\}\{|l|\}\{\\rule[-2mm]\{-2mm\}\{0.5cm\}\{\\bf Description\}~\\vline~ \n";
- print "\\parbox\{${parawidth}\}\{\\it $description\}\} \\\\ \n";
- print "\\hline \n";
- } else {
- print "\\begin\{tabular*\}\{$width\}\{|c|c|\@\{\\extracolsep\{\\fill\}\}r|\} \\hline \n";
- print "\{\\bf Name\} & \{\\bf Scope\} & \{\\bf Type\} \\\\ \n";
- print "\\hline \n";
- print "$name & $$table{\"scope\"} & $$table{\"type\"} \\\\ \n";
- print "\\hline \n";
+ # go through each group, then find all variables in the specific group type and generate the tables calling
+ # the function &CreateLatexTable
+ foreach my $group_type (sort keys %{$thorn{"groups"}})
+ {
+ foreach my $variable_name (sort @{$thorn{"groups"}{$group_type}})
+ {
+ # send in the 'variable' hash, the name of the variable, and the longest variable in this thorn
+ $latex_output .= &CreateLatexTable($thorn{"variables"}{$variable_name}, $variable_name);
+ }
}
- print "\\end\{tabular*\} \n\n";
-
- if ((($$table{"type"} ne "BOOLEAN") && ! $$table{"shared"}) && ($$table{"ranges"} > 0)) {
-
- print "\\vspace\{1mm\} \n\n";
-
- print "\\begin\{tabular*\}\{$width\}\{|c|l@\{\\extracolsep\{\\fill\}\}r|\} \\hline \n";
- print "\{\\bf Range\} & & \\\\ \n";
- print "\\hline\\hline \n";
-
- for ($i=1; $i <= $$table{"ranges"}; $i++) {
- $tempvar = $$table{"range $i description"};
- $tempvar =~ s/\_/\\\_/g;
+ print $latex_output;
+ ThornUtils::EndDocument($ofh, $document_type);
+}
- $tempvar2 = $$table{"range $i range"};
- $tempvar2 =~ s/\_/\\\_/g;
+#/*@@
+# @routine CreateLatexTable
+# @date Sun Mar 3 01:54:37 CET 2002
+# @author Ian Kelley
+# @desc
+# Creates a latex table for a given variable, returns the latex code to output
+# &CreateLatexTable(<variable hash>, <variable name>);
+#
+# @enddesc
+# @version
+#@@*/
+sub CreateLatexTable
+{
+ # get the stuff passed in, first is a hash of the given variable, second is the name of the variable,
+ # and third is the to-date longest variable in the thorn (for latex column formatting)
+ my %variable = %{$_[0]};
+
+ # get the different properties of the variable, and clean then up so we can output good latex
+ my $variable_name = ThornUtils::CleanForLatex($_[1]);
+ my $scope = ThornUtils::CleanForLatex($variable{"scope"});
+ my $default = ThornUtils::AddQuotes(ThornUtils::CleanForLatex($variable{"default"}));
+ my $description = ThornUtils::AddQuotes(ThornUtils::CleanForLatex($variable{"description"}));
+
+ # set some vars to hold the output we create
+ my $latex_output = "";
+ my $range_output = "";
+ my $extra_content = "";
+
+ # go through each range, check to see if we can find a longer variable for latex formatting,
+ # also compile the latex output for the ranges
+ for (my $i = 1; $i <= $variable{"ranges"}; $i++)
+ {
+ my $over_range = 1;
+ my $range = ThornUtils::AddQuotes(ThornUtils::CleanForLatex($variable{"range $i range"}));
+ my $range_desc = ThornUtils::AddQuotes(ThornUtils::CleanForLatex(ThornUtils::ChopVariable($variable{"range $i description"}, $MAX_VAR_LENGTH)));
- # new addition 4/2001
- $tempvar2 =~ s/\^/\\\^/g;
- $tempvar2 =~ s/\$/\\\$/g;
+ # generate latex output for this range
+ if (length($range) > $MAX_VAR_LENGTH)
+ {
+ $range_output .= "\\multicolumn{1}{|p{\\maxVarWidth}|}{see [$over_range] below} & \\multicolumn{2}{p{\\paraWidth}|}{$range_desc} \\\\";
+ $extra_content .= "\\noindent {\\bf [$over_range]} \\noindent \\begin{verbatim}". ThornUtils::ChopVariable($range, ($TABLE_WIDTH-10)/2)."\\end{verbatim}";
- print "$tempvar2 & $tempvar & \\\\ \\hline \n";
+ $over_range++;
+ } else {
+ $range_output .= "\\multicolumn{1}{|p{\\maxVarWidth}|}{$range} & \\multicolumn{2}{p{\\paraWidth}|}{$range_desc} \\\\";
}
- print "\\end\{tabular*\} \n\n";
}
- print "\\vspace\{$spacing\} \n\n";
-} ## END :LatexTableElement:
+ # start the table (tabular) enviroment, printing out the 'name', 'scope' and 'type' of the variable
+ $latex_output .= "\\noindent \\begin{tabular*}{\\tableWidth}{|c|l\@{\\extracolsep{\\fill}}r|}\n\\hline\n\\multicolumn{1}{|p{\\maxVarWidth}}{$variable_name} & {\\bf Scope:} $scope & $variable{\"type\"} \\\\";
-#########################################################################
-# Find_Directories #
-# Finds the current directories that are not CVS stuff contained w/in#
-# the directory name that is sent to this function, used to find #
-# thorns and arrangements in this program. #
-#########################################################################
-sub Find_Directories {
- my(@good_directories);
- chdir ("$start_directory") || die "cannot chdir to $start_directory: $!";
-
- chdir("$_[0]") || die "cannot change directory to $_[0] : $!";
- open(LS, "ls -p|");
- while(chomp($name = <LS>)) {
- if ((($name =~ /\/$/) && ($name ne "History/")) && ($name ne "CVS/")) {
- $name =~ s#/##;
- push(@good_directories, $name);
+ # print out the ranges, do nothing for shared variables
+ if ($scope =~ /shared from/) {
+ if ($variable{"ranges"} >= 1) {
+ $latex_output .= "\\hline\n\\multicolumn{3}{|l|}{\\bf Extends ranges:}\\\\ \n\\hline";
}
- }
- close(LS);
- chdir ($start_directory);
- return (@good_directories);
-} ## END :Find_Directories:
-
-#########################################################################
-# SortByType #
-# Sorts the ouput by "type" within their respective thorns, as we can#
-# have repetitive variable names within different thorns, currently #
-# output is restricted to internal (within thorn) sorting. #
-#########################################################################
-sub SortByType {
- if (lc($$a{"type"}) cmp lc($$b{"type"}) < 0) {
- return -1;
- } elsif (lc($$a{"type"}) cmp lc($$b{"type"}) > 0) {
- return 1;
} else {
- return -1;
- }
-} ## END :SortByType:
+ $latex_output .= "\\hline\n\\multicolumn{3}{|p{\\descWidth}|}{{\\bf Description:} $description} \\\\\n\\hline";
-#########################################################################
-# SortByName #
-# Sorts the ouput by "name" within their respective thorns, as we can#
-# have repetitive variable names within different thorns, currently #
-# output is restricted to internal (within thorn) sorting. #
-#########################################################################
-sub SortByName {
- my ($first) = $$a{"name"};
- my ($second) = $$b{"name"};
-
- if (lc($first) cmp lc($second) < 0) {
- print "\n$first : $second -1";
- return -1;
- } elsif (lc($$a{"name"}) cmp lc($$b{"name"}) > 0) {
- print "\n$$a{\"name\"} : $$b{\"name\"} 0";
- return 1;
- } else {
- print "\n$$a{\"name\"} : $$b{\"name\"} -1 (2)";
- return -1;
- }
-} ## END :SortByName:
+ if ($default !~ /\w/) {
+ $default = "(none)";
+ }
-#########################################################################
-# Dump #
-# Function to dump output to the screen rather than to a .tex file #
-# table, this does NOT create latex, simple provides an easy way to #
-# view the variables from the command line without use of Latex. #
-#########################################################################
-sub Dump {
- my (@cur_group) = @_;
-
- print "\n$thorn variables:\n";
-
- foreach $value (@cur_group) {
- if (lc($$value{"thorn"}) eq lc($thorn)) {
- print "\t$value:\n";
- foreach $key (keys %$value) {
- print "\t\t$key -> $$value{$key}\n";
+ # print out the range headings if we have any ranges, otherwise just print a box for the default value
+ if ($variable{"ranges"} >= 1) {
+ $latex_output .= "{\\bf Range} & & {\\bf Default:} $default \\\\";
+ } else {
+ $latex_output .= " & & {\\bf Default:} $default \\\\";
}
- }
- }
-} ## END :Dump:
+ }
-#########################################################################
-# Clean #
-# Function to perform any cleaning that may need to be done to #
-# variables before they are put into a hash of their name. #
-#########################################################################
-sub Clean {
-} ## END :Clean:
+ # insert the range data compiled earlier in a foreach loop
+ $latex_output .= $range_output;
+ # end the table
+ $latex_output .= "\\hline\n\\end{tabular*}\n\n\\vspace{1cm}";
-##########################
-# Reads in the thornlist #
-##########################
-sub Read_ThornList
+ # return the output, tacking on the $extra_content, which will be any variable ranges that exceeded
+ # the MAX_VAR_LENGTH restriction (for fitting into the boxes correctly)
+ return $latex_output . $extra_content;
+}
+
+#/*@@
+# @routine FindMaxVarLen
+# @date Sun Mar 3 01:54:37 CET 2002
+# @author Ian Kelley
+# @desc
+# Finds the maximum length of all the ranges and variable names, to be used for setting the
+# length of the different table cells.
+# &FindMaxVarLen(<thorn hash>);
+#
+# @enddesc
+# @version
+#@@*/
+sub FindMaxVarLen
{
- my ($thornlist) = shift;
+ my %thorn = %{$_[0]};
+ my $max_len = "";
+# my $temp = "";
+
+ # we are going to go through each variable name and range name to see where
+ # the largest text is, then we will use this for later formatting of our
+ # latex tables (so we do not get paragraph run-off
+ foreach my $variable (keys %thorn)
+ {
+ # we will always take the variable length as the standard maximum length,
+ # regardless of if it is longer than MAX_VAR_LENGTH
+ $max_len = length($variable) > length($max_len) ? $variable : $max_len;
- chomp($directory);
+ for (my $i = 1; $i <= $thorn{$variable}{"ranges"}; $i++)
+ {
+ my $range = $thorn{$variable}{"range $i range"};
- open (TL, "$thornlist")
- || die "cannot open thornlist ($thornlist) for reading: $!";
+ $range =~ s/^\s*(.*?)\s*$/$1/;
- while (<TL>)
- {
- s/(.*?)#.*/\1/; # read up to the first "#"
- s/\s+//g; # replace any spaces with nothing
- if (/\w+/) {
- $thornlist{$_} = 1;
+ # if this new length is greater than the last one, but less than the max allowed
+ # length, then we asign the maximum variable length to this new length
+ if ((length($range) > length($max_len)) && (length($range) < $MAX_VAR_LENGTH)) {
+ $max_len = $range;
+ }
}
}
- close TL;
+
+ return $max_len;
}
diff --git a/lib/sbin/SchedLatex.pl b/lib/sbin/SchedLatex.pl
new file mode 100755
index 00000000..88f8031a
--- /dev/null
+++ b/lib/sbin/SchedLatex.pl
@@ -0,0 +1,540 @@
+#!/usr/bin/perl -s
+
+#/*@@
+# @file SchedLatex.pl
+# @date Sun Mar 3 19:05:41 CET 2002
+# @author Ian Kelley
+# @desc
+# This program will take as input a thornlist, and outputs a latex table
+# that contains the information in the thorns' schedule.ccl file(s). This latex
+# table can then be used as a stand-alone document, or as a section of a large
+# "ThornGuide"
+# @enddesc
+# @version
+#@@*/
+
+#########################
+# ->> SchedLatex.pl <<- #
+#########################################################################
+# Standard HELP Function #
+#########################################################################
+if ($h || $help) {
+ print "--> SchedLatex.pl <--\n";
+ print "Options:\n";
+ print "\t-thornlist= : (opt) list specific thorns to process\n";
+ print "\t-th= : (semi opt) thorn to process\n";
+ print "\t-arr= : (semi opt) arrangement to process\n";
+ print "\t-processall : (opt) process all arrangements\n";
+ print "\n";
+ print "\t-directory= : (opt) dir. of arrangements (default arrangements/)\n";
+ print "\t-outdir= : (opt) directory to dump output files, default is .\n";
+ print "\n";
+ print "\t-grouping= : (opt) file ouput grouping scope (bythorn/byarrangement/all)\n";
+ print "\t-width= : (opt) fixed width of table (default 160mm)\n";
+ print "\t-document : (opt) creates a TeX document, not just a table\n";
+ print "\t-section : (opt) makes this a section of a greater document\n";
+ print "\n";
+ print "\t-debug : (opt) prints thorn name on each schedule \n";
+ print "\t-verbose : (opt) gives verbose output to screen\n";
+ print "\t-dump : (opt) dumps output to screen, not in Latex\n";
+ print "\t-h/-help : (opt) this screen\n";
+ print "\nExample:\n";
+ print "\tperl -s /lib/sbin/SchedLatex.pl -processall -outdir=testdirectory -grouping=all -document\n";
+ exit 0;
+}
+
+#########################################################################
+# #
+# This program will take as input a thorn, and output a latex table #
+# that contains the information in that thorns schedule.ccl file. #
+# #
+#########################################################################
+
+##############
+# REQUIRE(S) #
+##############
+$cctk_home .= '/' if (($cctk_home !~ /\/$/) && defined $cctk_home);
+
+$sbin_dir = "${cctk_home}lib/sbin";
+require "$sbin_dir/ScheduleParser.pl";
+require "$sbin_dir/CSTUtils.pl";
+
+# common procedures used to create the thornguide(s)
+require "$sbin_dir/ThornUtils.pm";
+
+# for reading of the thornlist routine: %thorns = &ReadThornlist($thornlist)
+require "$sbin_dir/MakeUtils.pl";
+
+
+###########################
+# COMMAND LINE VAR. CHECK #
+###########################
+$sort ||= "name";
+$width ||= "160mm";
+
+if (((! $th) && (! $arr)) && ((! defined $processall) && (! defined $thornlist))) {
+ die "\nNo -th= or -arr= (or -processall or -thornlist) specified, nothing to process!\n";
+}
+
+$grouping ||="bythorn";
+
+##################
+# INITIALIZATION #
+##################
+$start_directory=`pwd`;
+chomp($start_directory);
+# set some variables in ThornUtils(.pm) namespace
+$ThornUtils::cctk_home = $cctk_home;
+$ThornUtils::start_directory = $start_directory;
+$ThornUtils::verbose = $verbose;
+$ThornUtils::debug = $debug;
+
+
+# get/setup the output directory and the arrangements directory
+$outdir = ThornUtils::SetupOutputDirectory($outdir);
+$arrangements_dir = ThornUtils::GetArrangementsDir($directory);
+
+if (! $directory) {
+ $directory = $arrangements_dir;
+} elsif ($directory !~ /\/$/) {
+ $directory .= '/';
+}
+
+if (defined $thornlist) {
+ %thornlist = &ReadThornlist($thornlist);
+ #&Read_ThornList($thornlist);
+ $processall = 1;
+}
+
+#################################################
+# FIND THORN(S)/ARRANGEMENT(S) AND CREATE LATEX #
+#################################################
+
+if (defined $document) {
+ $document_type = "document";
+} else {
+ $document_type = "section";
+}
+
+@arrangements = ThornUtils::FindDirectories($directory);
+
+$ofh = ThornUtils::StartDocument("schedule", "MasterTable", $outdir, $arrangement, "Schedule", $document_type) if ((! $dump) && ($grouping eq "all"));
+#&StartDocument("MasterTable") if ((! $dump) && ($grouping eq "all"));
+
+foreach $arrangement (sort @arrangements)
+{
+ @thorns = ThornUtils::FindDirectories($directory . $arrangement);
+
+ $ofh = ThornUtils::StartDocument("schedule", "", $outdir, $arrangement, "Schedule", $document_type) if ((! $dump) && ($grouping eq "byarrangement"));
+ #&StartDocument($arrangement) if ((! $dump) && ($grouping eq "byarrangement"));
+ foreach $thorn (@thorns)
+ {
+ next if ($thorn !~ /\w/);
+
+ if (($processall) || (($thorn eq $th) || ($arr eq $arrangement)))
+ {
+ ## do not create a file for this thorn if it is not in the THORNLIST (if one is specified)
+ next if ((defined $thornlist) && (! defined $thornlist{"$arrangement/$thorn"}));
+
+ if (-e "$directory$arrangement/${thorn}/schedule.ccl")
+ {
+ $ofh = ThornUtils::StartDocument("schedule", $thorn, $outdir, $arrangement, "Schedule", $document_type) if ((! $dump) && ($grouping eq "bythorn"));
+ #&StartDocument($thorn, $arrangement) if ((! $dump) && ($grouping eq "bythorn"));
+
+ $$thorn{$thorn} = "${directory}${arrangement}/${thorn}";
+
+ # we are selecting STDOUT so that any junk from the &create_schedule_database won't get in our output
+ $filehandle = select(STDOUT);
+ %parameter_database = &create_schedule_database(%$thorn);
+ select($filehandle);
+
+ &ReadLatexDatabase(%parameter_database);
+ &LatexTableElement;
+ #&EndDocument if ((! $dump) && ($grouping eq "bythorn"));
+ ThornUtils::EndDocument($ofh, $document_type) if ((! $dump) && ($grouping eq "bythorn"));
+ print "\n\\newpage" if ($grouping eq "all");
+
+ ###################################################
+ # reset the variables in case they are used again #
+ foreach my $b (%statements) {
+ undef %$b;
+ }
+ undef %statements;
+
+ foreach my $b (%blocks) {
+ undef %$b;
+ }
+ undef %blocks;
+ # END of reset #
+ ################
+ }
+ }
+ }
+ #&EndDocument if ((! $dump) && ($grouping eq "byarrangement"));
+ ThornUtils::EndDocument($ofh, $document_type) if ((! $dump) && ($grouping eq "byarrangement"));
+
+}
+#&EndDocument if ((! $dump) && ($grouping eq "all"));
+ThornUtils::EndDocument($ofh, $document_type) if ((! $dump) && ($grouping eq "all"));
+
+print "\n" if ($verbose);
+#########################################################################
+# END OF MAIN SECTION OF THE PROGRAM #
+#########################################################################
+
+#########################################################################
+# BEGINNING OF SUB-ROUTINES #
+#########################################################################
+
+#########################################################################
+# ReadLatexDataBase #
+# Calls schedule_parser.pl, which will read in the schedule.ccl file #
+# from a single thorn and return all data as a %hash table, which we #
+# will then parse to put into our own %hash tables named according to #
+# the variable names. #
+# #
+# %(variable_name) : any number of hashes created with their names #
+# being the variable names, they then have $keys #
+# (descriptions) with $values (well, values) #
+# (e.g.) $name{"default"} = "Cactus"; #
+#########################################################################
+sub ReadLatexDatabase
+{
+ my (%parameter_database) = @_;
+ my ($field);
+ my ($name, $lname, $conditionals) = "";
+
+ foreach $field (sort keys %parameter_database)
+ {
+ print STDERR "\n\"$field --> $parameter_database{$field}\"" if ($verbose);
+
+ if ($field =~ /(.*?)\s(.*?)\s(.*)/)
+ {
+ ($name,$block,$var) = ($1,$2,$3);
+ chomp($parameter_database{$field});
+
+ $$block{$var} = $parameter_database{$field};
+
+ $$block{"CONDITIONAL"} = "0";
+ $$block{"THORN"} = $name;
+
+ if ($block =~ /^BLOCK/) {
+ $blocks{$block} = 1;
+ } else {
+ $statements{$block} = 1;
+ }
+ }
+ } #-- foreach
+
+ # conditional blocks
+ $conditionals = $parameter_database{"$name FILE"};
+ foreach my $key (keys %blocks)
+ {
+ $key =~ /BLOCK\_(\d+)/;
+ my $b = "\@BLOCK\@$1";
+
+ while ($conditionals =~ /\bif\b.*?\{(.*?)\}/imgs)
+ {
+ my $if = $1;
+ if ($if =~ /\Q$b\E/) {
+ $$key{"CONDITIONAL"} = "true";
+ }
+ }
+ }
+
+ #conditional statements
+ $conditionals = $parameter_database{"$name FILE"};
+ foreach my $key (keys %statements)
+ {
+ $key =~ /STATEMENT\_(\d+)/;
+ my $b = "\@STATEMENT\@$1";
+
+ while ($conditionals =~ /\bif\b.*?\{(.*?)\}/imgs)
+ {
+ my $if = $1;
+ if ($if =~ /\Q$b\E/) {
+ $$key{"CONDITIONAL"} = "true";
+ }
+ }
+ }
+
+ print "\n";
+ return $name;
+} ## END :ReadLatexDatabase:
+
+#########################################################################
+# LatexTableElement #
+# Takes whatever table element is currently reffered to by $table #
+# and prints it out into a LaTeX table. Only nifty things it curr. #
+# does is NOT print ranges for BOOLEAN and SHARED elements. #
+#########################################################################
+sub LatexTableElement
+{
+ my $go = 1;
+ my $i = 0;
+ my $printgridtitle = 1;
+ my @conditional_statements;
+ my @always_statements;
+ my %aliases;
+
+ print "\n\n (For Debug, the thorn is: " . &Clean($thorn) . ")" if ($debug);
+
+
+ foreach my $st (sort keys %statements)
+ {
+ my @groups = split/,/,$$st{"GROUPS"};
+ my $type = $$st{"TYPE"};
+
+ if ($type eq "STOR")
+ {
+ if ($$st{"CONDITIONAL"}) {
+ push @conditional_statements, @groups;
+ } else {
+ push @always_statements, @groups;
+ }
+ }
+ }
+
+ # who has the most elements?
+ $len = @conditional_statements > @always_statements ? @conditional_statements : @always_statements;
+
+ print "\n\n\\noindent This section lists all the variables which are assigned storage by thorn ". &Clean($thorn) . ". Storage can either last for the duration of the run ({\\bf Always} means that if this thorn is activated storage will be assigned, {\\bf Conditional} means that if this thorn is activated storage will be assigned for the duration of the run is some condition is met), or can be turned on for the duration of a schedule function.\n\n";
+
+ print "\n\\subsection\*\{Storage\}";
+ if (@conditional_statements > 0 || @always_statements > 0)
+ {
+ print "\n\n\\hspace\{5mm\}\n\n \\begin\{tabular*\}\{$width\}\{ll\} \n";
+ print @always_statements > 0 ? "\n\{\\bf Always:\}" : "~";
+ print "& ";
+ print @conditional_statements > 0 ? "\{\\bf Conditional:\} \\\\ \n" : " ~ \\\\ \n";
+
+ for ($i = 0; $i <= $len; $i++)
+ {
+ print $always_statements[$i] !~ /^$/ ? &Clean($always_statements[$i]) : "~";
+ print " & ";
+ print $conditional_statements[$i] !~ /^$/ ? &Clean($conditional_statements[$i]) : "~";
+ print "\\\\ \n";
+ }
+ print "\\end\{tabular*\} \n\n";
+ } else {
+ print "NONE";
+ }
+
+ $printgridtitle = 1;
+ $k = 0;
+
+ foreach $group (sort by_block keys %blocks)
+ {
+ next if ($group =~ /^$/);
+
+ print "\n\\subsection\*\{Scheduled Functions\}" if ($printgridtitle); $printgridtitle=0;
+ print "\n \\vspace\{5mm\}\n\n";
+ print "\\noindent \{\\bf " . &Clean($$group{"WHERE"}) . "\} ";
+ print $$group{"CONDITIONAL"} ? " (conditional) \n\n" : "\n\n";
+ print "\\hspace\{5mm\} ". ThornUtils::ToLower(&Clean($$group{"NAME"})) . " \n";
+ print "\n\\hspace\{5mm\}\{\\it ". ThornUtils::ToLower(&Clean($$group{"DESCRIPTION"})) . " \} \n";
+ print "\n\n\\hspace\{5mm\}\n\n \\begin\{tabular*\}\{$width\}\{cll\} \n";
+
+ print "~& Language: &" . ThornUtils::ToLower(&Clean($$group{"LANG"})) . "\\\\ \n" if ($$group{"LANG"} !~ /^$/);
+ print "~& After: &" . ThornUtils::ToLower(&Clean($$group{"AFTER"})) . "\\\\ \n" if ($$group{"AFTER"} !~ /^$/);
+
+ if (my @storage = split/,/, ThornUtils::ToLower(&Clean($$group{"STOR"})) ) {
+ print "~& Storage: & "; #~ \\\\ \n" if ($$group{"STOR"} !~ /^$/);
+ my $fp = 1;
+ foreach (@storage) {
+ if ($fp) {
+ print "$_ \\\\ \n";
+ $fp = 0;
+ } else {
+ print "~& ~ &" . $_. "\\\\ \n";
+ }
+ }
+ } else {
+ print "~& Storage: &" . ThornUtils::ToLower(&Clean($$group{"STOR"})) . "\\\\ \n" if ($$group{"STOR"} !~ /^$/);
+ }
+
+ print "~& Triggers: &" . ThornUtils::ToLower(&Clean($$group{"TRIG"})) . "\\\\ \n" if ($$group{"TRIG"} !~ /^$/);
+ print "~& Sync: &" . ThornUtils::ToLower(&Clean($$group{"SYNC"})) . "\\\\ \n" if ($$group{"SYNC"} !~ /^$/);
+
+ $aliases{$$group{"NAME"}} = $$group{"AS"};
+
+ delete $$group{"CONDITIONAL"};
+ delete $$group{"WHERE"};
+ delete $$group{"DESCRIPTION"};
+ delete $$group{"LANG"};
+ delete $$group{"AFTER"};
+ delete $$group{"STOR"};
+ delete $$group{"TRIG"};
+ delete $$group{"SYNC"};
+ delete $$group{"AS"};
+ delete $$group{"NAME"};
+ delete $$group{"THORN"};
+
+ $i = 0;
+ foreach $group_key (sort keys %$group)
+ {
+ next if ($$group{$group_key} =~ /^$/);
+
+ $clean_name = ThornUtils::Translate(&Clean($group_key));
+ $clean_var = &Clean($vars[$i]);
+ $clean_value = ThornUtils::ToLower(&Clean($$group{$group_key}));
+
+ $j = 1;
+ if (@clean_values = split/,/,$clean_value)
+ {
+ foreach $clean_value (@clean_values)
+ {
+ next if ($clean_value !~ /\w/);
+ if ($j) {
+ print $clean_var . "& $clean_name: & $clean_value \\\\ \n";
+ $j = 0;
+ } else {
+ print "~ & ~ & $clean_value \\\\ \n";
+ }
+ }
+ } else {
+ print $clean_var . "& $clean_name: & $clean_value \\\\ \n";
+ }
+
+ $i++;
+ }
+ print "\\end\{tabular*\} \n\n";
+ }
+
+ # delete aliases where they key equals the value
+ foreach my $key (keys %aliases) {
+ if ($key eq $aliases{$key}) {
+ delete $aliases{$key};
+ }
+ }
+
+ if (scalar(keys %aliases) > 0)
+ {
+ print "\n\\subsection\*\{Aliased Functions\}";
+ print "\n\n\\hspace\{5mm\}\n\n \\begin\{tabular*\}\{$width\}\{ll\} \n";
+ print "\n\{\\bf Alias Name:\} ~~~~~~~& \{\\bf Function Name:\} \\\\ \n";
+
+ foreach my $key (sort keys %aliases) {
+ print &Clean($key) ." & ". &Clean($aliases{$key}) ." \\\\ \n";# if ($key ne $aliases{$key});
+ }
+ print "\\end\{tabular*\} \n\n";
+ }
+
+ print "\n\n\\vspace\{5mm\}";
+}
+
+#################################################
+# Cleans up a value, so latex is happy with it. #
+#################################################
+sub Clean
+{
+ my $val = shift;
+
+ $val =~ s/^\s*?\"//;
+ $val =~ s/\"$//;
+ $val =~ s/\_/\\\_/g;
+ $val =~ s/\$/\\\$/g;
+
+ return $val;
+} ## END :Clean:
+
+#########################################################################
+# SortByType #
+# Sorts the ouput by "type" within their respective thorns, as we can#
+# have repetitive variable names within different thorns, currently #
+# output is restricted to internal (within thorn) sorting. #
+#########################################################################
+sub SortByType {
+ if (lc($$a{"type"}) cmp lc($$b{"type"}) < 0) {
+ return -1;
+ } elsif (lc($$a{"type"}) cmp lc($$b{"type"}) > 0) {
+ return 1;
+ } else {
+ return -1;
+ }
+
+} ## END :SortByType:
+
+#########################################################################
+# SortByName #
+# Sorts the ouput by "name" within their respective thorns, as we can#
+# have repetitive variable names within different thorns, currently #
+# output is restricted to internal (within thorn) sorting. #
+#########################################################################
+sub SortByName {
+ my ($first) = $$a{"name"};
+ my ($second) = $$b{"name"};
+
+ if (lc($first) cmp lc($second) < 0) {
+ print "\n$first : $second -1";
+ return -1;
+ } elsif (lc($$a{"name"}) cmp lc($$b{"name"}) > 0) {
+ print "\n$$a{\"name\"} : $$b{\"name\"} 0";
+ return 1;
+ } else {
+ print "\n$$a{\"name\"} : $$b{\"name\"} -1 (2)";
+ return -1;
+ }
+
+} ## END :SortByName:
+
+#########################################################################
+# Dump #
+# Function to dump output to the screen rather than to a .tex file #
+# table, this does NOT create latex, simple provides an easy way to #
+# view the variables from the command line without use of Latex. #
+#########################################################################
+sub Dump {
+ my (@cur_group) = @_;
+
+ print "\n$thorn variables:\n";
+
+ foreach $value (@cur_group)
+ {
+ if (lc($$value{"thorn"}) eq lc($thorn)) {
+ print "\t$value:\n";
+ foreach $key (keys %$value) {
+ print "\t\t$key -> $$value{$key}\n";
+ }
+ }
+ }
+
+} ## END :Dump:
+
+#########################################################################
+# Clean #
+# Function to perform any cleaning that may need to be done to #
+# variables before they are put into a hash of their name. #
+#########################################################################
+sub DUMP {
+ select STDOUT;
+ print "\n$thorn\n";
+ foreach my $b (sort by_block keys %blocks) {
+ print "\n\t$b";
+ foreach my $key (sort keys %$b) {
+ print "\n\t\t$key = $$b{$key}" if ($key ne "THORN");
+ }
+ }
+ foreach my $b (sort by_block keys %statements) {
+ print "\n\t$b";
+ foreach my $key (sort keys %$b) {
+ print "\n\t\t$key = $$b{$key}" if ($key ne "THORN");
+ }
+ }
+}
+
+##########################
+# Sorting function #
+##########################
+sub by_block {
+ my $i,j;
+ $a =~ /\_(.*)/;
+ $i = $1;
+ $b =~ /\_(.*)/;
+ $j = $1;
+
+ return 1 if ($i > $j);
+ return -1 if ($i < $j);
+ return 0;
+}
+
diff --git a/lib/sbin/ThornGuide.pl b/lib/sbin/ThornGuide.pl
index ed0ec227..d7bbb10e 100644
--- a/lib/sbin/ThornGuide.pl
+++ b/lib/sbin/ThornGuide.pl
@@ -1,5 +1,7 @@
#!/usr/local/bin/perl
+#######################
+# -> ThornGuide.pl <- #
##########################################################################
# Create cactus documentation based upon documenation provided by thorns #
# in the current checkout being examined. #
@@ -17,9 +19,13 @@ $mydir = `pwd`;
chomp($mydir);
$mydir =~ s/\/lib\/sbin\/$//;
-########
-# HELP #
-########
+
+$TODAYS_DATE = `date +%B%d%Y`;
+$TODAYS_DATE =~ s/(.*?)(\d{2})(\d{4})/$1 $2, $3/;
+
+#################
+# HELP FUNCTION #
+#################
if ($help || $h) {
print "--> ThornGuide.pl <--\n";
print "Options:\n";
@@ -35,7 +41,6 @@ if ($help || $h) {
exit 0;
}
-############################
# get directory to process #
if (! $directory)
{
@@ -48,14 +53,13 @@ if (! $directory)
$directory = "$mydir/$directory";
}
-if (! ($directory =~ /\/$/) ) {
- $directory .= '/';
-}
+$directory .= '/' if ($directory !~ /\/$/);
print STDERR "\nProcessing: $directory" if ($verbose);
# what are we going to process, if we are processing a directory?
-if (defined $directory) {
+if (defined $directory)
+{
if ($directory =~ /arrangements\/(.*?)\//) {
$arrangement = $1;
print "\nProcessing one arrangement" if ($verbose);
@@ -87,31 +91,23 @@ if (! $outdir) {
print STDERR "\nCreating directory: $start_directory/$outdir" if ($verbose);
}
}
- if (! ($outdir =~ /\/$/)) {
- $outdir .= "/";
- }
+ $outdir .= '/' if ($outdir !~ /\/$/);
}
-###################
# specify outfile #
-if (! $outfile) {
- $outfile = "ThornGuide.tex";
-}
+$outfile = "ThornGuide.tex" if (! $outfile);
-############################
# open the file for output #
-open (OUT, ">$outdir$outfile") || die "\ncannot open $outdir$outfile: $!";
+open (OUT, ">$outdir$outfile") || die "\nCannot open $outdir$outfile for output: $!";
-###########
## START ##
-###########
&Output_Top;
-
+# process a directory or a thornlist
if (! $thornlist) {
- &Recur($directory); # if we are processing a directory
+ &Recur($directory);
} else {
- @foundfiles = &Read_ThornList($thornlist, $directory); # thornlist
+ @foundfiles = &Read_ThornList($thornlist, $directory);
}
#############################################################
@@ -121,18 +117,13 @@ foreach (@foundfiles)
s/^$directory//;
/(.*?)\/(.*?)\//;
- $arr = $1; # get arrangements and thorn names
- $thorn =$2;
+ ($arr, $thorn) = ($1, $2);
- if (! defined $arrangements{$arr}) { # hash of arrangements
- $arrangements{$arr} = $1;
- }
- push @$arr, $thorn; # hash of arrangements & thorns
- # print STDERR "\nFound: $_" if ($verbose);
-}
-# #
-##############################################################
+ # hash of arrangements
+ $arrangements{$arr} = $1 if (! defined $arrangements{$arr});
+ push @$arr, $thorn;
+}
##############################################################
# Iterates through our known arrangements, then its thorns, #
@@ -141,7 +132,7 @@ foreach (@foundfiles)
#########################################
# if we are processing all arrangements #
if ($level eq "all_arr") {
- $i=1; # $i = "cactuspart" counter
+ $i = 1; # $i = "cactuspart" counter
foreach $arrangement (sort keys %arrangements)
{
&Start_Arr($arrangement,$i); # begins a "cactuspart"
@@ -168,14 +159,11 @@ if ($level eq "all_arr") {
&Output_Bottom;
print STDERR "\nFinished\n" if ($verbose);
-#print "\n";
+
#######################
## END OF MAIN STUFF ##
#######################
-
-
-
####################################################################
# BEGINNING OF SUB-ROUTINES #
####################################################################
@@ -190,9 +178,9 @@ print STDERR "\nFinished\n" if ($verbose);
####################################################################
sub Read_Thorn_Doc
{
- my ($path) = shift;
- my ($contents) = "";
- my ($pathandfile);
+ my ($path) = shift;
+ my ($contents) = "";
+ my ($pathandfile) = "";
my ($start) = 0;
my ($stop) = 0;
@@ -206,17 +194,23 @@ sub Read_Thorn_Doc
{
if (/\\end\{document\}/) { # stop reading
$stop = 1;
- $contents .= "\n\\include{${arrangement}_${thorn}_par}\n";
+ $contents .= "\n\\include{${arrangement}_${thorn}_param}\n";
+ $contents .= "\n\\include{${arrangement}_${thorn}_inter}\n";
+ $contents .= "\n\\include{${arrangement}_${thorn}_schedule}\n";
}
if ($start && ! $stop) { # add to $contents
s/(\\includegraphics.*?\{)\s*?(.*\.eps\s*?\})/$1$path\/$2/g;
$contents .= $_;
} elsif (/\\begin\{document\}/) { # don't begin yet.... 1st flag
- $temp = 1;
+ $temp = 1;
}
- if (($temp) && ( /\\section\{/ )) { # start reading
+ if (($temp) && ( /\\section\{/ ) ) {
+ #if (($temp) && (( /\\section\{/ ) || (/\\abstract\{/)) ) { # start reading
+ # if (/\\abstract\{/) {
+ # s/\\abstract\{/\\section\{Abstract\}\\begin\{paragraph\}\{/;
+ # }
$start = 1;
$contents = $_;
$temp = 0;
@@ -225,14 +219,18 @@ sub Read_Thorn_Doc
# if it never started reading, then we print some error message
if (! $start) {
+ $tmp2 = $arrangement;
+ $tmp2 =~ s/\_/\\\_/g;
$tmp = $thorn;
$tmp=~ s/\_/\\\_/g;
if (-e $pathandfile) {
- $contents = "Could not parse latex documentation for $arrangement/$tmp($file)";
+ $contents = "Could not parse latex documentation for $tmp2/$tmp($file)";
} else {
- $contents = "Could not find latex documentation for $arrangement/$tmp ($file)";
+ $contents = "Could not find latex documentation for $tmp2/$tmp ($file)";
}
- $contents .= "\n\n\\include{${arrangement}\_${thorn}\_par}\n";
+ $contents .= "\n\n\\include{${arrangement}\_${thorn}\_param}\n";
+ $contents .= "\n\\include{${arrangement}\_${thorn}\_inter}\n";
+ $contents .= "\n\\include{${arrangement}\_${thorn}\_schedule}\n";
}
close DOC;
@@ -279,6 +277,7 @@ sub Start_Arr
my ($arr) = shift;
my ($partnum) = shift;
+ $arr =~ s/\_/\\\_/g;
print OUT <<EOC;
\\begin{cactuspart}{$partnum}{$arr}{}{}
@@ -305,32 +304,23 @@ sub Read_ThornList
{
my ($thornlist) = shift;
my ($directory) = shift;
- my (@temp);
my (@tl);
chomp($directory);
open (TL, "$thornlist")
- || die "cannot open thornlist ($thornlist) for reading: $!";
+ || die "\nCannot open thornlist ($thornlist) for reading: $!";
while (<TL>)
{
+ next if /\s*?\!/;
s/(.*?)#.*/\1/; # read up to the first "#"
s/\s+//g; # replace any spaces with nothing
if (/\w+/) {
- push @temp, $_; # add to array if something is left
+ push @tl, "$directory$_/doc/$file";
}
}
- foreach $tempvar (@temp) # see if docs exist for these thorns
- {
-# if (-e "$directory$tempvar/doc/$file") {
- push @tl, "$directory$tempvar/doc/$file";
-# } else {
-# print "\nCannot find: $tempvar/doc/$file" if ($verbose);
-# }
- }
-
return @tl;
}
@@ -365,9 +355,11 @@ sub Recur
#print STDERR "\n$dir\t\tNo $file, no param.ccl" if ($verbose);
}
}
+
foreach (@dirs) { # look in sub directories
&Recur("$dir$_");
}
+
return;
}
@@ -378,6 +370,14 @@ sub Output_Top
{
print OUT <<EOC;
+\\newif\\ifpdf
+\\ifx\\pdfoutput\\undefined
+ \\pdffalse % we are not running PDFLaTeX
+\\else
+ \\pdfoutput=1 % we are running PDFLaTeX
+ \\pdftrue
+\\fi
+
\\documentclass{report}
\\usepackage{fancyhdr}
@@ -515,7 +515,7 @@ print OUT <<EOC;
\\begin{document}
-\\cactustitlepage{Thorn Guide}{Revision: }{Date: 2000/12/07}
+\\cactustitlepage{Thorn Guide}{Date of Creation:}{$TODAYS_DATE}
\\dominitoc
\\setcounter{page}{1}
@@ -532,6 +532,11 @@ print OUT <<EOC;
\\renewcommand{\\thepage}{\\Alph{part}\\arabic{page}}
\\pagestyle{fancy}
+\\newlength{\\tableWidth}
+\\newlength{\\maxVarWidth}
+\\newlength{\\paraWidth}
+\\newlength{\\descWidth}
+
\\newpage
%%%%%%%%%%%%%%%%%%%%%%%
EOC
diff --git a/lib/sbin/ThornList.pl b/lib/sbin/ThornList.pl
new file mode 100644
index 00000000..dd7a55d4
--- /dev/null
+++ b/lib/sbin/ThornList.pl
@@ -0,0 +1,111 @@
+#!/usr/bin/perl
+
+#/*@@
+# @file ThornList.pl
+# @date March 2001
+# @author Ian Kelley
+# @desc
+# Either creates a stripped down thornlist of all thorns in the arrangments
+# directory, or prints out the full paths to each thorn on a single line
+#
+# Used primary by the ThornGuide Makefile
+# @enddesc
+# @version
+#@@*/
+
+# give help
+if ($h || $help) {
+ print <<EOC;
+--> ThornList.pl <--
+
+Either creates a stripped down thornlist of all thorns in the arrangments directory, or prints out the full paths to each thorn on a single line
+
+Usage:
+\t\$ perl -s ThornList.pl -arrangements_dir=/home/ikelley/Cactus/WaveToyC_Dev/arrangements > allthorns.th
+\t\$ perl -s ThornList.pl -arrangements_dir=/home/ikelley/Cactus/WaveToyC_Dev/arrangements -thornlist=allthorns.th
+EOC
+
+exit 0;
+}
+
+if (! defined $arrangements_dir) {
+ die "\nArrangements directory not defined (-arrangments_dir)";
+} elsif ($arrangments_dir !~ /\/$/) {
+ $arrangements_dir .= '/';
+}
+
+# if we are building a thornlist from thorns in $arrangements_dir
+if (! defined $thornlist)
+{
+ @arrangements = &FindDirectories($arrangements_dir);
+
+ foreach $arrangement (@arrangements)
+ {
+ @thorns = &FindDirectories("$arrangements_dir$arrangement");
+
+ foreach $thorn (@thorns) {
+ print "\n$arrangement/$thorn";
+ }
+ }
+}
+# if we are printing all the thorn directories on one line
+# for use by the ThornGuide makefile
+else
+{
+ $thorn_paths = "";
+
+ open (THORNLIST, "<$thornlist") || die "\nCannot open thornlist ($thornlist): $!";
+
+ while (<THORNLIST>)
+ {
+ next if /\s*?\!/; # bypass any directives
+ s/(.*?)#.*/\1/; # read up to the first "#"
+ s/\s+//g; # replace any spaces with nothing
+
+ next if ! /\w/; # nothing on this line?
+
+ $thorn_paths .= "$arrangements_dir$_ ";
+
+ }
+
+ close (THORNLIST);
+
+ print $thorn_paths;
+}
+## END: MAIN ##
+
+#/*@@
+# @routine FindDirectories
+# @date Sun Mar 3 01:54:37 CET 2002
+# @author Ian Kelley
+# @desc
+# Grabs all directories within a given directory, minus the ones created by CVS
+# @enddesc
+# @version
+#@@*/
+
+sub FindDirectories
+{
+ my (@good_directories);
+
+ chdir ("$start_directory") || die "\nCannot chdir to $start_directory: $!";
+
+ chdir("$_[0]") || die "\nCannot change directory to $_[0] : $!";
+
+ open(LS, "ls -F|");
+
+ while(chomp($name = <LS>))
+ {
+ next if (! -d $name);
+ if (($name ne "History/") && ($name ne "CVS/"))
+ {
+ $name =~ s#/##;
+ push(@good_directories, $name);
+ }
+ }
+
+ close(LS);
+
+ chdir ($start_directory);
+ return (@good_directories);
+} ## END :Find_Directories:
diff --git a/lib/sbin/ThornUtils.pm b/lib/sbin/ThornUtils.pm
new file mode 100644
index 00000000..7880009f
--- /dev/null
+++ b/lib/sbin/ThornUtils.pm
@@ -0,0 +1,703 @@
+package ThornUtils;
+
+#/*@@
+# @file ThornUtils.pm
+# @date Sun Mar 3 19:05:41 CET 2002
+# @author Ian Kelley
+# @desc
+# This file contains any common routines that are used by the scripts to create the
+# Cactus ThornGuide. Currently the files that implement this package are:
+# InterLatex.pl, ParamLatex.pl, SchedLatex.pl, ThornGuide.pl
+# @enddesc
+# @version
+#@@*/
+
+#/*@@
+# @routine ReadThornlist
+# @date Sun Mar 3 01:54:37 CET 2002
+# @author Ian Kelley
+# @desc
+# Reads in a thornlist and returns the arrangements/thorns, strips out all the comments/etc.
+#
+# THIS FUNCTION IS PROVIDED BY "MakeUtils.pl"
+#
+# @enddesc
+# @version
+#@@*/
+
+#/*@@
+# @routine CreateThornlist
+# @date Sun Mar 3 01:54:37 CET 2002
+# @author Ian Kelley
+# @desc
+# Takes an input directory (arrangements directory), calls &FindDirectories to get all
+# the sub-directories (arrangements), then calls &FindDirectories once more to get all
+# the sub-sub-directories (thorns), then returns a thornlist.
+# @thorns = &CreateThornlist($arrangements_dir);
+# @enddesc
+# @version
+#@@*/
+sub CreateThornlist
+{
+ my ($arrangementsDir) = shift;
+
+ my (@foundThorns, @arrangements, @thorns);
+
+ @arrangements = &FindDirectories($arrangementsDir);
+
+ foreach my $arrangement (@arrangements)
+ {
+ @thorns = &FindDirectories("${arrangementsDir}${arrangement}");
+
+ foreach my $thorn (@thorns) {
+ push @foundThorns, "${arrangement}/${thorn}";
+ }
+ }
+
+ return @foundThorns;
+}
+
+#/*@@
+# @routine FindDirectories
+# @date Sun Mar 3 01:54:37 CET 2002
+# @author Ian Kelley
+# @desc
+# Grabs all directories within a given directory, minus the ones created by CVS
+# @directories = &FindDirectories($directory);
+# @enddesc
+# @version
+#@@*/
+sub FindDirectories
+{
+ my ($directory) = shift;
+
+ my (@directories);
+
+ chdir ($start_directory) || die "\nCannot change directory to $start_directory: $!";
+
+ chdir($directory) || die "\nCannot change directory to $directory: $!";
+
+ open(LS, "ls -F|");
+
+ while( chomp($name = <LS>))
+ {
+ next if ((! -d $name) || ($name eq "History/") || ($name eq "CVS/"));
+
+ $name =~ s/\/$//;
+ push(@directories, $name);
+ }
+
+ close(LS);
+
+ chdir ($start_directory) || die "\nCannot change directory to $start_directory: $!";
+
+ return (@directories);
+}
+
+#/*@@
+# @routine GetArrangementsDir
+# @date Sun Mar 3 19:05:41 CET 2002
+# @author Ian Kelley
+# @desc
+# assumes $cctk_home and $start_directory are already defined
+# &GetArrangementsDir(<indir>)
+# @enddesc
+# @calls
+# @calledby
+# @history
+#
+# @endhistory
+#
+#@@*/
+sub GetArrangementsDir
+{
+ my ($indir) = shift;
+
+ if ($indir =~ /^$/) {
+ $indir = "${cctk_home}arrangements";
+ } elsif ($indir !~ /^\//) {
+ $indir = "$start_directory/arrangements";
+ }
+
+ $indir .= '/' if ($indir !~ /\/$/);
+
+ return ($indir);
+}
+
+#/*@@
+# @routine SetupOutputDirectory
+# @date Sun Mar 3 19:05:41 CET 2002
+# @author Ian Kelley
+# @desc
+# Sets up the output directory, assigning it to the CWD if it is blank, trys to
+# resolve it if it is relative (by using $start_directory),
+# &SetupOutputDirectory($outdir);
+# @enddesc
+# @calls
+# @calledby
+# @history
+#
+# @endhistory
+#
+#@@*/
+sub SetupOutputDirectory
+{
+ my ($outdir) = shift;
+
+ # set $outdir to the CWD
+ if ($outdir =~ /^$/) {
+ $outdir = "./";
+ }
+ else
+ {
+ # we have an relative path, tack $cctk_home on the front
+ if ($outdir !~ /^\//) {
+ $outdir = "$start_directory/$outdir";
+ }
+
+ # create the directory if it does not exist
+ if (! -d $outdir) {
+ mkdir($outdir, 0755) || die "\nCannot create directory ($outdir): $!";
+ print STDERR "\nCreating directory: $outdir" if ($verbose);
+ }
+ $outdir .= '/' if ($outdir !~ /\/$/);
+ }
+
+ print STDERR "\nOutput directory is: $outdir" if ($verbose);
+
+ return ($outdir);
+}
+
+#/*@@
+# @routine ClassifyThorns
+# @date Sun Mar 3 19:05:41 CET 2002
+# @author Ian Kelley
+# @desc
+# Goes through and classifies thorns based upon arrangement, takes a hash reference and an array
+# listing thorns (e.g. CactusWave/WaveToyC) as input, and then assigns the keys to be the
+# arrangement names, with values as references to an array of thorn names
+#
+# &ClassiftyThorns(<hash reference>, <array>)
+#
+# To fill a hash by using &ClassifyThorns:
+# %arrangements;
+# &ClassifyThorns(\%arrangements, @listOfThorns);
+#
+# To iterate through the hash, printing out all values:
+# foreach my $arrangement (keys %arrangements) {
+# print "\n$arrangement";
+# foreach my $thorn (@{$arrangements{$arrangement}}) {
+# print "\n\t$thorn";
+# }
+# }
+# @enddesc
+# @calls
+# @calledby
+# @history
+#
+# @endhistory
+#
+#@@*/
+sub ClassifyThorns
+{
+ my ($rhArr) = shift;
+
+ # My most efficient code yet! (I am so proud)
+
+ # We add keys (arrangements) to the hash passed in ($rhArr) which are references
+ # to a list of thorns for each arrangement.
+ foreach (@_) {
+ /^(.*?)\/(.*?)$/;
+ push @{$$rhArr{$1}}, $2;
+ }
+}
+
+
+#/*@@
+# @routine GetThornPaths
+# @date Sun Mar 3 19:05:41 CET 2002
+# @author Ian Kelley
+# @desc
+# This function will cut up a list of thorns (@listOfThorns), check if a given file
+# exists in that directory ($interestingFile), if so, then it will add a key/value
+# pair to the hash (%paths) that represents the thorn name (key) and location (value)
+# %paths = &GetThornPaths(\@listOfThorns, $arrangementsDir, $interestingFile);
+# @enddesc
+# @calls
+# @calledby
+# @history
+#
+# @endhistory
+#
+#@@*/
+sub GetThornPaths
+{
+ my ($rlListOfThorns) = shift;
+ my ($arrangementsDir) = shift;
+ my ($interestingFile) = shift;
+ my ($keepArrInKey) = shift;
+
+ my %paths;
+
+ foreach (@$rlListOfThorns) {
+ /^(.*?)\/(.*?)$/;
+ if (($interestingFile eq "") || (-e "${arrangementsDir}${_}/${interestingFile}")) {
+ my $key = $keepArrInKey ? "$1/$2" : "$1";
+ $paths{$key} = "$arrangementsDir$_";
+ }
+ }
+ return %paths;
+}
+
+#/*@@
+# @routine StartDocument
+# @date Sun Mar 3 19:05:41 CET 2002
+# @author Ian Kelley
+# @desc
+# Opens a file for output, and selects it as standard out. returning the old
+# filehandle. The output filename is determined depending on how things are
+# grouped (by thorn, arrangement, or all together) and the type of the program
+# that invoked the function (interface, schedule, or parameter)
+#
+# Depending on the $docType, this will either create a 'section' to be included
+# by a a larger .tex file, or it will create a new self-contained file.
+#
+# Example, to create an 'Interfaces section' for thorn CactusBase/IOBasic
+# $ofh = &StartDocument("inter", "IOBasic", "/tmp/", "CactusBase", "Interfaces", "section");
+# @enddesc
+# @calls
+# @calledby
+# @history
+#
+# @endhistory
+#
+#@@*/
+sub StartDocument
+{
+ my ($programType, $groupName, $outdir, $arrangement, $sectionName, $docType) = @_;
+ my $oldfilehandle;
+
+ my $outfile = $outdir;
+
+ if (! defined $groupName) {
+ die "\nCannot group tables for output, internal error in &StartDocument";
+ }
+
+ chdir ($start_directory) || die "\nCannot change directory to $start_directory";
+
+ $outfile .= $arrangement !~ /^$/ ? "${arrangement}_" : "";
+ $outfile .= "${groupName}_${programType}.tex";
+
+ open(OUT, ">$outfile") || die "\nCannot open $outfile for output: $!";
+ $oldfilehandle = select OUT;
+
+ if ($docType eq 'document') {
+ print "\\documentclass[12pt,a4paper]\{article\} \n";
+ print "\\begin\{document\} \n\n";
+ print "\n\\noindent \\section{$sectionName}\n\n";
+ } elsif ($docType eq 'section') {
+ print "\n\\section{$sectionName} \n\n";
+ }
+
+ return $oldfilehandle;
+}
+
+#/*@@
+# @routine EndDocument
+# @date Sun Mar 3 19:05:41 CET 2002
+# @author Ian Kelley
+# @desc
+# Ends a LaTeX document (if -document) specified, and closes the OUT
+# file, which is used to write the LaTeX table to.
+# &EndDocument(<old file handle>, <section, document>);
+# @enddesc
+# @calls
+# @calledby
+# @history
+#
+# @endhistory
+#
+#@@*/
+sub EndDocument
+{
+ my ($oldfilehandle, $docType) = @_;
+
+ if ($docType eq 'document') {
+ print "\\end\{document\} \n";
+ }
+ close OUT;
+
+ select $oldfilehandle;
+}
+
+#/*@@
+# @routine CleanForLatex
+# @date Sun Mar 3 19:05:41 CET 2002
+# @author Ian Kelley
+# @desc
+# Cleans up our values so that latex will not give us errors.
+# $val = &CleanForLatex($val);
+# @enddesc
+# @calls
+# @calledby
+# @history
+#
+# @endhistory
+#
+#@@*/
+sub CleanForLatex
+{
+ my $val = shift;
+
+ #$val =~ s/\\/\\\\/g;
+ $val =~ s/^\s*?\"\s*?/\"/;
+ $val =~ s/\s*?\"\s*?$/\"/;
+ $val =~ s/\_/\\\_/g;
+ $val =~ s/\$/\\\$/g;
+ $val =~ s/\^/\\\^/g;
+ $val =~ s/\*/\\\*/g;
+
+ return $val;
+}
+
+#/*@@
+# @routine Translate
+# @date Sun Mar 3 19:05:41 CET 2002
+# @author Ian Kelley
+# @desc
+# Takes a value, uppercases the first letter and lowercases all others
+# $val = &Translate($val);
+# @enddesc
+# @calls
+# @calledby
+# @history
+#
+# @endhistory
+#
+#@@*/
+sub Translate
+{
+ my $val = shift;
+ my $temp = "";
+
+ $val =~ s/^(.)//;
+ $temp = $1;
+ $temp =~ tr/a-z/A-Z/;
+ $val =~ tr/A-Z/a-z/;
+
+ return ($temp.$val);
+}
+
+
+#/*@@
+# @routine ToUpper
+# @date Sun Mar 3 19:05:41 CET 2002
+# @author Ian Kelley
+# @desc
+# Translates values passed in to upper case and returns it
+# $val = &ToUpper($val);
+# @enddesc
+# @calls
+# @calledby
+# @history
+#
+# @endhistory
+#
+#@@*/
+sub ToUpper
+{
+ my ($val) = shift;
+
+ $val =~ tr/a-z/A-Z/;
+ return $val;
+}
+
+#/*@@
+# @routine ToLower
+# @date Sun Mar 3 19:05:41 CET 2002
+# @author Ian Kelley
+# @desc
+# Translates values passed in to lower case and returns it
+# $val = &ToLower($val);
+# @enddesc
+# @calls
+# @calledby
+# @history
+#
+# @endhistory
+#
+#@@*/
+sub ToLower
+{
+ my ($val) = shift;
+
+ $val =~ tr/A-Z/a-z/;
+ return $val;
+}
+
+#/*@@
+# @routine CreateSystemDatabase
+# @date Sun Mar 3 19:05:41 CET 2002
+# @author Ian Kelley
+# @desc
+# Creates a system database, used by create_interface_database.
+# &CreateSystemDatabase(<hash reference>);
+# @enddesc
+# @calls
+# @calledby
+# @history
+#
+# @endhistory
+#
+#@@*/
+sub CreateSystemDatabase
+{
+ my ($rh) = shift;
+
+ $$rh{"CCTK_HOME"} = $cctk_home;
+
+ if (! defined $config_dir) {
+ $$rh{"CONFIG_DIR"} = "${cctk_home}config-data";
+ }
+
+ if (! defined $bindings_dir) {
+ $$rh{"BINDINGS_DIR"} = "${cctk_home}bindings";
+ }
+}
+
+#/*@@
+# @routine Dump
+# @date Sun Mar 3 01:54:37 CET 2002
+# @author Ian Kelley
+# @desc
+# This routine will 'dump' out some data-structure when given a reference to it. It becomes useful
+# (for debugging) to dump the contents of something like:
+# $database{"Computer"}->{"Programming Languages"}->{"Scripting"}->{"Perl"}->{"Users"} = \@users;
+# &Dump(\%database);
+#
+# It should be noted that this is primary dealing with references to stuff, so if
+# this routine is used on something that is not a reference, it may not work properly.
+# (e.g. &Dump(@myarray) will only print the first element of @myarray)
+# but: &Dump(\@myarray) will print them all... etc etc
+#
+# Note: unless it isn't abundently obvious, this is all recurrsion.
+# @enddesc
+# @calls Dump DumpHash DumpArray
+# @version
+#@@*/
+sub Dump
+{
+ my ($ref_type) = ref($_[0]);
+
+ print " [$ref_type]" if ($debug>1);
+ if ($ref_type eq "HASH") {
+ # we want to print out a hash, so we call the routine that
+ # knows how to properly iterate through one
+ &DumpHash(@_);
+ } elsif ($ref_type eq "ARRAY") {
+ # routine that iterates through an array/list
+ &DumpArray(@_);
+ } elsif ($ref_type eq "REF") {
+ # go to next level, maybe someday we get a real 'value'
+ &Dump(${$_[0]}, $_[1]);
+ } else {
+ # scalar, or whatever, print it out.
+ print "\n" . " " x $_[1] . $_[0];
+ }
+
+ return;
+}
+
+#/*@@
+# @routine DumpHash
+# @date Sun Mar 3 01:54:37 CET 2002
+# @author Ian Kelley
+# @desc
+# Outputs a hash, or, if that hash contains references, calls &Dump
+#
+# Note: This is an INTERNAL FUNCTION
+# @enddesc
+# @calledby Dump
+# @version
+#@@*/
+sub DumpHash
+{
+ my ($hr, $iteration) = @_;
+
+ foreach my $key (keys %$hr)
+ {
+ print "\n" . " " x $iteration . $key;
+ if (! (my $refType = ref($$hr{$key}) )) {
+ print " = $$hr{$key}";
+ } else {
+ &Dump($$hr{$key}, $iteration+3);
+ }
+ }
+}
+
+#/*@@
+# @routine DumpArray
+# @date Sun Mar 3 01:54:37 CET 2002
+# @author Ian Kelley
+# @desc
+# Outputs an array, or, if that array contains references, calls &Dump
+#
+# Note: This is an INTERNAL FUNCTION
+# @enddesc
+# @calledby Dump
+# @version
+#@@*/
+sub DumpArray
+{
+ my ($ar, $iteration) = @_;
+
+ foreach my $key (@$ar)
+ {
+ if (! (my $refType = ref($key) )) {
+ print "\n" . " " x $iteration . $key;
+ } else {
+ &Dump($key, $iteration+3);
+ }
+ }
+}
+
+#/*@@
+# @routine ProcessAllArrangements
+# @date Sun Mar 3 01:54:37 CET 2002
+# @author Ian Kelley
+# @desc
+# Will loop through all keys of the hash reference passed in, then for
+# each key, it will call &ProcessOneArrangement, this routine has been separated
+# from ProcessOneArrangement, so that ProcessOneArrangement can be called
+# independently if needed, and to add more flexiblity in the future.
+# &ProcessAllArrangements(\%arrangements);
+# @enddesc
+# @calls ProcessOneArrangement
+# @calledby
+# @version
+#@@*/
+sub ProcessAllArrangements
+{
+ # get the arrangements hash
+ my ($hrArrangements) = shift;
+
+ # go through and find each arrangement
+ foreach my $arrangement (keys %$hrArrangements) {
+ &ProcessOneArrangement($$hrArrangements{$arrangement}, $arrangement);
+ }
+}
+
+#/*@@
+# @routine ProcessOneArrangement
+# @date Sun Mar 3 01:54:37 CET 2002
+# @author Ian Kelley
+# @desc
+# Will loop through all keys of the hash reference passed in, then for
+# each key, it will call &ProcessOneThorn in the MAIN perl file to process
+# the appropriate thorn (e.g. output latex)
+#
+# It calls the &ProcessOneThorn in the MAIN perl file because depending on
+# what type of parsing one is doing (interface, schedule, parameter), the
+# keys, sort mechanisms and datatypes in the (thorn) hash will differ.
+# &ProcessOneArrangement(\%arrangement);
+# @enddesc
+# @calls ProcessOneThorn (in MAIN perl file)
+# @calledby ProcessAllArrangements
+# @version
+#@@*/
+sub ProcessOneArrangement
+{
+ # get the (single) arrangement hash
+ my ($hrArr) = shift;
+ my ($arrangement) = shift;
+
+ foreach my $thorn (keys %$hrArr) {
+ # please note, you will not get good results unless a sub-routine called
+ # ProcessOneThorn exists in your main perl file. (where this is called from)
+ main::ProcessOneThorn($$hrArr{$thorn}, $arrangement, $thorn);
+ }
+}
+
+
+#/*@@
+# @routine AddQuotes
+# @date Sun Mar 3 01:54:37 CET 2002
+# @author Ian Kelley
+# @desc
+# Simply takes away any enclosing quotes if they exist, and then adds enclosing quotes.
+# @enddesc
+# @version
+#@@*/
+sub AddQuotes {
+ my $var = shift;
+ $var =~ s/^\s*?\"(.*)\"\s*?$/$1/;
+ return "\"$var\"";
+}
+
+#/*@@
+# @routine SetWidth
+# @date Sun Mar 3 01:54:37 CET 2002
+# @author Ian Kelley
+# @desc
+# This function defines some latex variables for setting the width of the table we will later display.
+# It does this by defining the total table width, and then subtracting the different values for the
+# table elements, so we can use these variables to set the widths of different cells in the table.
+#
+# @enddesc
+# @version
+#@@*/
+sub SetWidth
+{
+ my $width = shift;
+ my $longest_var = shift;
+
+ my $latex_output = "";
+
+#\\newlength{\\tableWidth}
+
+#\\newlength{\\maxVarWidth}
+#\\newlength{\\paraWidth}
+#\\newlength{\\descWidth}
+$latex_output = <<END;
+
+\\setlength{\\tableWidth}{${width}mm}
+
+\\setlength{\\paraWidth}{\\tableWidth}
+\\setlength{\\descWidth}{\\tableWidth}
+\\settowidth{\\maxVarWidth}{$longest_var}
+
+\\addtolength{\\paraWidth}{-\\maxVarWidth}
+\\addtolength{\\paraWidth}{-\\columnsep}
+\\addtolength{\\paraWidth}{-\\columnsep}
+\\addtolength{\\paraWidth}{-\\columnsep}
+
+\\addtolength{\\descWidth}{-\\columnsep}
+\\addtolength{\\descWidth}{-\\columnsep}
+\\addtolength{\\descWidth}{-\\columnsep}
+END
+
+return ($latex_output);
+}
+
+#/*@@
+# @routine ChopVariable
+# @date Sun Mar 3 01:54:37 CET 2002
+# @author Ian Kelley
+# @desc
+# If a variable has a sequence of numbers longer than the given value ($split) that does
+# not contain a space, it will add a space and newline after this sequence
+#
+# @enddesc
+# @version
+#@@*/
+sub ChopVariable
+{
+ my $var = shift;
+ my $split = shift;
+
+ $var =~ s/([^\s]{$split})/$1 \n/g;
+ return $var;
+}
+
+
+1;