#/***************************************************************************** ## Copyright (C) 1994-2008 by David Gordon. ## All rights reserved. ## ## This software is part of a beta-test version of the Consed/Autofinish ## package. It should not be redistributed or ## used for any commercial purpose, including commercially funded ## sequencing, without written permission from the author and the ## University of Washington. ## ## This software is provided ``AS IS'' and any express or implied ## warranties, including, but not limited to, the implied warranties of ## merchantability and fitness for a particular purpose, are disclaimed. ## In no event shall the authors or the University of Washington be ## liable for any direct, indirect, incidental, special, exemplary, or ## consequential damages (including, but not limited to, procurement of ## substitute goods or services; loss of use, data, or profits; or ## business interruption) however caused and on any theory of liability, ## whether in contract, strict liability, or tort (including negligence ## or otherwise) arising in any way out of the use of this software, even ## if advised of the possibility of such damage. ## ## Building Consed from source is error prone and not simple which is ## why I provide executables. Due to time limitations I cannot ## provide any assistance in building Consed. Even if you do not ## modify the source, you may introduce errors due to using a ## different version of the compiler, a different version of motif, ## different versions of other libraries than I used, etc. For this ## reason, if you discover Consed bugs, I can only offer help with ## those bugs if you first reproduce those bugs with an executable ## provided by me--not an executable you have built. ## ## Modifying Consed is also difficult. Although Consed is modular, ## some modules are used by many other modules. Thus making a change ## in one place can have unforeseen effects on many other features. ## It may takes months for you to notice these other side-effects ## which may not seen connected at all. It is not feasable for me to ## provide help with modifying Consed sources because of the ## potentially huge amount of time involved. ## ##*****************************************************************************/ #!/usr/bin/perl -w $SIG{__WARN__} = dieWhenGetWarning; sub dieWhenGetWarning { my $szErrorMessage = shift; die "$szErrorMessage"; } $szMainCPP = "main.cpp"; if ( -e "$szMainCPP" ) { unlink( "$szMainCPP" ) || die "couldn't delete $szMainCPP"; } $szInputFile = "makeMainCPP.txt"; open( filInput, "$szInputFile" ) || die "couldn't open $szInputFile"; $szWhatIsRunning = "whatIsRunning.h"; $szUsageFile = "main.cpp_part3"; $szVariablesFile = "main.cpp_part4"; $szFigureOutGroup = "main.cpp_part6"; # main.cpp_part6b has the beginning of the loop that actually reads # and records the arguments $szCheckArgumentsFile = "main.cpp_part7"; # main.cpp_part8 has the end of the loop that reads the arguments # and a few custom argument checking $szCheckCompatibilityFile = "main.cpp_part9"; $szCheckIfAceFileOnCommandLine = "main.cpp_part10"; # main.cpp_part11 has the actual starting of each of the different programs # combined into the consed executable @aFilesToCat = qw/ main.cpp_part1 main.cpp_part3 main.cpp_part4 main.cpp_part5 main.cpp_part6 main.cpp_part6b main.cpp_part7 main.cpp_part8 main.cpp_part9 main.cpp_part10 main.cpp_part11 /; @aComputerWrittenFiles = qw/ whatIsRunning.h main.cpp_part3 main.cpp_part4 main.cpp_part6 main.cpp_part7 main.cpp_part9 main.cpp_part10 main.cpp /; foreach $szComputerWrittenFile ( @aComputerWrittenFiles ) { if ( -e "$szComputerWrittenFile" ) { unlink( "$szComputerWrittenFile" ) || die "couldn't delete $szComputerWrittenFile so can write a new one"; } } open(filWhatIsRunning, ">$szWhatIsRunning" ) || die "couldn't open $szWhatIsRunning for output"; open( filUsage, ">$szUsageFile" ) || die "couldn't open $szUsageFile for write"; open( filVariables, ">$szVariablesFile" ) || die "couldn't open $szVariablesFile for write"; open( filCheckArguments, ">$szCheckArgumentsFile" ) || die "couldn't open $szCheckArgumentsFile for write"; open( filCheckCompatibility, ">$szCheckCompatibilityFile" ) || die "couldn't open $szCheckCompatibilityFile for write"; open( filCheckIfAceFileOnCommandLine, ">$szCheckIfAceFileOnCommandLine" ) || die "couldn't open $szCheckIfAceFileOnCommandLine for write"; open( filFigureOutGroup, ">$szFigureOutGroup" ) || die "couldn't open $szFigureOutGroup"; print filWhatIsRunning "#ifndef whatIsRunning_included\n"; print filWhatIsRunning "#define whatIsRunning_included\n"; print filWhatIsRunning "\n\n\n"; print filUsage "\n\n\n// main.cpp_part3\n\n\n"; print filVariables "\n\n\n// main.cpp_part4\n\n\n"; print filCheckArguments "\n\n\n// main.cpp_part7\n\n\n"; print filCheckCompatibility "\n\n\n// main.cpp_part9\n\n\n"; print filCheckIfAceFileOnCommandLine "\n\n\n// main.cpp_part10\n\n\n"; # want this to look like this: # static char* aszWhatIsRunning[] = { # "graphical_consed", # "-autoFinish", # "-autoEdit", # "-autoReport", # "-autoPCRAmplify", # "-addReads", # "-addNewReads", # "-addAlignedSequence", # "-printSingleSignal", # "-tagSNPs" # }; @aGroupLines = (); while( ) { if ( /^BEGIN_GROUPS/ ) { last; } } while( ) { if ( /^END_GROUPS/ ) { last; } chomp; push( @aGroupLines, $_ ); } if ( $#aGroupLines == -1 ) { die "something wrong in $szInputFile since no groups"; } for( $n = 0; $n <= $#aGroupLines; ++$n ) { $szGroupLine = $aGroupLines[ $n ]; @aWords = split(' ', $szGroupLine ); print filWhatIsRunning "const int " . $aWords[0] . " = $n;\n"; } print filWhatIsRunning "\n\n\n"; %aArgumentsThatDeterminePrograms = (); print filWhatIsRunning "static char* aszWhatIsRunning[] = {\n"; for( $n = 0; $n <= $#aGroupLines; ++$n ) { $szGroupLine = $aGroupLines[ $n ]; @aWords = split(' ', $szGroupLine ); if ( $#aWords != 1 ) { die "group line $_ should have had exactly 2 tokens"; } $szArgument = $aWords[1]; $aArgumentsThatDeterminePrograms{ lc( $szArgument ) } = 1; print filWhatIsRunning " \"$szArgument\""; if ( $n != $#aGroupLines ) { print filWhatIsRunning ",\n"; } else { print filWhatIsRunning "\n"; } } print filWhatIsRunning "};\n\n\n"; print filWhatIsRunning "#endif\n"; print filFigureOutGroup "\n\n\n\n"; print filFigureOutGroup "// $szFigureOutGroup start\n"; print filFigureOutGroup " int nWhatIsRunning = nGraphicalConsedIsRunning;\n"; print filFigureOutGroup "\n"; print filFigureOutGroup " // nWhatIsRunning might be changed below--\n"; print filFigureOutGroup " // nGraphicalConsedIsRunning is just the default\n"; print filFigureOutGroup "\n"; print filFigureOutGroup " for( n = 1; n < nArgc; ++n ) {\n"; print filFigureOutGroup " RWCString soLowerCaseArg( argv[n] );\n"; print filFigureOutGroup " soLowerCaseArg.toLower();\n"; # do not check for 0th element (error) or graphical consed which has # no argument. I've put an error condition for the 0th argument in case # pCP->nWhatIsRunning_ doesn't get set for( $nGroup = 0; $nGroup <= $#aGroupLines; ++$nGroup ) { if ( $aGroupLines[ $nGroup ] =~ /^nError/ ) { next; } if ( $aGroupLines[ $nGroup ] =~ /nGraphicalConsedIsRunning/ ) { next; } print filFigureOutGroup " if ( soLowerCaseArg % aszWhatIsRunning[ $nGroup ] ) {\n"; print filFigureOutGroup " // check if a group has already been assigned\n"; print filFigureOutGroup " if ( nWhatIsRunning != nGraphicalConsedIsRunning ) {\n"; print filFigureOutGroup " cerr << \"Fatal Error: arguments \" << aszWhatIsRunning[ nWhatIsRunning ] << \" and \" << argv[n] << \" are mutually incompatible\" << endl;\n"; print filFigureOutGroup " exit( -1 );\n"; print filFigureOutGroup " }\n"; print filFigureOutGroup "\n"; print filFigureOutGroup " nWhatIsRunning = $nGroup;\n"; print filFigureOutGroup " }\n"; } # for( $nGroup = 0; $nGroup <= $#aGroupLines; ++$nGroup ) { print filFigureOutGroup " }\n"; print filFigureOutGroup " // when reached here, we know that the user has not specified running more\n"; print filFigureOutGroup " // than one program and we have determined what that program is\n"; print filFigureOutGroup " if ( nWhatIsRunning != nGraphicalConsedIsRunning )\n"; print filFigureOutGroup " cerr << aszWhatIsRunning[ nWhatIsRunning ] << \" will be run.\" << endl;\n"; print filUsage "\n\n\n\n"; print filUsage "//$szUsageFile starts\n"; print filUsage "\n"; print filUsage "static RWCString soUsage = \n\"\\\n"; # will write: # static RWCString soUsage = # "\ # print filVariables "\n"; print filVariables "int main(int nArgc, char* argv[]) {\n"; print filVariables "\n"; outerLoop: while( 1 ) { # keep reading blank lines until we find one that isn't blank $szArgumentLine = ""; while( $szArgumentLine eq "" ) { if ( !defined( $szArgumentLine = ) ) { last outerLoop; } chomp( $szArgumentLine ); } @aArguments = split(' ', $szArgumentLine ); $szArgument = $aArguments[0]; defined( $szVariableLine = ) || die "premature end of file $szInputFile when processing $szArgument"; chomp( $szVariableLine ); defined( $szAllowedGroupsForThisArgument = ) || die "premature end of file 2 $szInputFile when processing $szArgument"; # check that no typos in my files. All allowed groups (programs) should # have been listed at in the BEGIN_GROUPS section @aAllowedGroupsForThisArgument = split(' ', $szAllowedGroupsForThisArgument ); foreach $szAllowedGroup ( @aAllowedGroupsForThisArgument ) { if ( substr( $szAllowedGroup, 0, 1 ) eq "?" ) { next; } if ( $szAllowedGroup eq "graphical_consed" ) { next; } if ( !exists $aArgumentsThatDeterminePrograms{ lc( $szAllowedGroup ) } ) { die "argument $szArgument says it is in program $szAllowedGroup which I don't recognize as being in the BEGIN_GROUPS section at top"; } } defined( $szIsAceFileRequiredLine = ) || die "premature end of file 4 $szInputFile when processing $szArgument"; defined( $szShouldThisFeatureBeDocumented = ) || die "premature end of file 5 $szInputFile when processing $szArgument"; ( $szKeyword, $szYesOrNo ) = split(' ', $szShouldThisFeatureBeDocumented ); if ( $szKeyword ne "show:" ) { die "line $szShouldThisFeatureBeDocumented for $szArgument should have been show: yes or show: no"; } if ( $szYesOrNo eq "yes" ) { $bShowUser = 1; } elsif ( $szYesOrNo eq "no" ) { $bShowUser = 0; } else { die "line $szShouldThisFeatureBeDocumented for $szArgument should have been show: yes or show: no"; } $bLeaveLoopLater = 0; if ( !defined( $szValueLine = )) { $bLeaveLoopLater = 1; $szValueLine = ""; }; chomp( $szValueLine ); $szErrorMessage = ""; if ( $szValueLine ne "" ) { defined( $szErrorMessage = ) || die "premature end of file 3 $szInputFile when processing $szArgument"; chomp( $szErrorMessage ); if ( !defined( $szBlankLine = ) ) { $bLeaveLoopLater = 1; } else { chomp( $szBlankLine ); if ( $szBlankLine ne "" ) { die "line should have been blank but is:$szBlankLine\nand follows $szErrorMessage"; } } } if ( $bShowUser ) { print filUsage "$szArgument\\n\\\n"; # writes \n\(new line) if ( $szErrorMessage ne "" ) { print filUsage " $szErrorMessage\\n\\\n"; } } print filVariables " $szVariableLine = false;\n"; $szLowerCaseArgument = lc( $szArgument ); if ( $#aArguments == 0 ) { print filCheckArguments " else if ( soLowerCaseArg == \"$szLowerCaseArgument\" ) {\n"; } else { print filCheckArguments " else if ( ( soLowerCaseArg == \"$szLowerCaseArgument\" ) " ; for( $nArgument = 1; $nArgument <= $#aArguments; ++$nArgument ) { $szFurtherArgument = $aArguments[ $nArgument ]; $szLowerCaseFurtherArgument = lc( $szFurtherArgument ); print filCheckArguments " || ( soLowerCaseArg == \"$szLowerCaseFurtherArgument\" )\n"; } printf filCheckArguments " ) {\n"; } $szVariable = ( split(' ', $szVariableLine ))[1]; print filCheckArguments " $szVariable = true;\n"; if ( $szValueLine ne "" ) { print filCheckArguments " ++n;\n"; print filCheckArguments " if ( n >= nArgc ) {\n"; print filCheckArguments " cerr << \"Fatal Error: $szErrorMessage\" << endl;\n"; print filCheckArguments " exit( -1 );\n"; print filCheckArguments " }\n"; $szValueVariable = ( split(' ', $szValueLine ))[1]; print filCheckArguments " $szValueVariable = argv[n];\n"; print filVariables " $szValueLine;\n"; } print filCheckArguments " }\n"; # now print compatibilities code if ( ( $szAllowedGroupsForThisArgument !~ /^\?/ ) && !exists( $aArgumentsThatDeterminePrograms{ $szLowerCaseArgument } ) ) { print filCheckCompatibility " if ( $szVariable ) {\n"; $szGroup = $aAllowedGroupsForThisArgument[0]; $nGroupConstant = &nConvertGroupStringToConstant( $szGroup ); print filCheckCompatibility " if ( ( nWhatIsRunning != $nGroupConstant )\n"; for ( $nGroup = 1; $nGroup <= $#aAllowedGroupsForThisArgument; ++$nGroup ) { $szGroup = $aAllowedGroupsForThisArgument[$nGroup ]; $nGroupConstant = &nConvertGroupStringToConstant( $szGroup ); print filCheckCompatibility " && ( nWhatIsRunning != $nGroupConstant )\n"; } print filCheckCompatibility " ) {\n"; print filCheckCompatibility " cerr << \"$szArgument cannot be used with \" << aszWhatIsRunning[ nWhatIsRunning ] << endl;\n"; print filCheckCompatibility " cerr << \"$szArgument must only be used with: \" << endl;\n"; foreach $szAllowedGroup ( @aAllowedGroupsForThisArgument ) { print filCheckCompatibility " cerr << \" $szAllowedGroup\" << endl;\n"; } print filCheckCompatibility " exit( -1 );\n"; print filCheckCompatibility " }\n"; print filCheckCompatibility " }\n"; } # if ( $szAllowedGroupsForThisArgument =~ /^\?/ ) { # now print whether this argument requires the -ace (ace file ) if ( $szIsAceFileRequiredLine =~ /^-ace/ ) { print filCheckIfAceFileOnCommandLine " if ( $szVariable && !bAceFileOnCommandLine ) {\n"; print filCheckIfAceFileOnCommandLine " cerr << \"Error: If you specify $szArgument, you must also specify -ace (ace file)\" << endl;\n"; print filCheckIfAceFileOnCommandLine " exit( -1 );\n"; print filCheckIfAceFileOnCommandLine " }\n"; } elsif ( $szIsAceFileRequiredLine =~ /^no-ace/ ) { print filCheckIfAceFileOnCommandLine " if ( $szVariable && bAceFileOnCommandLine ) {\n"; print filCheckIfAceFileOnCommandLine " cerr << \"Error: If you specify $szArgument, you must not also specify -ace (ace file)\" << endl;\n"; print filCheckIfAceFileOnCommandLine " exit( -1 );\n"; print filCheckIfAceFileOnCommandLine " }\n"; } elsif( $szIsAceFileRequiredLine =~ /^\?-ace/ ) { # no op } else { die "line $szIsAceFileRequiredLine should be one of -ace, no-ace, or ?-ace"; } if ( $bLeaveLoopLater ) { last; } } print filUsage "\";\n"; close( filInput ); close( filWhatIsRunning ); close( filUsage ); close( filVariables ); close( filCheckArguments ); close( filCheckCompatibility ); close( filCheckIfAceFileOnCommandLine ); close( filFigureOutGroup ); $szCommand = "cat "; foreach $szMainFile ( @aFilesToCat ) { $szCommand .= " $szMainFile"; } $szCommand .= " >$szMainCPP"; !system( $szCommand ) || die "couldn't execute $szCommand"; foreach $szFileToSetReadOnly ( @aComputerWrittenFiles ) { if ( chmod( 0444, "$szFileToSetReadOnly" ) != 1 ) { die "couldn't chmod 0444 $szFileToSetReadOnly"; } } ##################### subroutines #################### sub addCommas { ( $nOriginal ) = @_; ( $nWithCommas = $nOriginal ) =~ s/(?<=\d)(?=(\d\d\d)+$)/,/g; return $nWithCommas; } sub min { my ( $a, $b ) = @_; if ( $a < $b ) { return $a; } else { return $b; } } sub max { my ( $a, $b ) = @_; if ( $a < $b ) { return $b; } else { return $a; } } # this just makes, e.g., autoFinish into nAutoFinish sub nConvertGroupStringToConstant { my ( $szGroup ) = @_; if ( $szGroup eq "graphical_consed" ) { return "nGraphicalConsedIsRunning"; } if ( substr( $szGroup, 0, 1 ) eq "-" ) { $szGroup = substr( $szGroup, 1 ); } $cFirstLetter = substr( $szGroup, 0, 1 ); $cFirstLetter = uc( $cFirstLetter ); $szConstant = "n" . $cFirstLetter . substr( $szGroup, 1 ) . "IsRunning"; return $szConstant; }