1#!/usr/bin/env perl 2# 3# @file translateTests.pl 4# @brief Converts C/C++ libSBML test into C#, Java, Python, and Ruby files. 5# @author Akiya Jouraku 6# @author Frank Bergmann (fbergman@u.washington.edu, C# additions) 7# 8#<!--------------------------------------------------------------------------- 9# This file is part of libSBML. Please visit http://sbml.org for more 10# information about SBML, and the latest version of libSBML. 11# 12# Copyright (C) 2013-2018 jointly by the following organizations: 13# 1. California Institute of Technology, Pasadena, CA, USA 14# 2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK 15# 3. University of Heidelberg, Heidelberg, Germany 16# 17# Copyright (C) 2009-2013 jointly by the following organizations: 18# 1. California Institute of Technology, Pasadena, CA, USA 19# 2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK 20# 21# Copyright (C) 2006-2008 by the California Institute of Technology, 22# Pasadena, CA, USA 23# 24# Copyright (C) 2002-2005 jointly by the following organizations: 25# 1. California Institute of Technology, Pasadena, CA, USA 26# 2. Japan Science and Technology Agency, Japan 27# 28# This library is free software; you can redistribute it and/or modify it 29# under the terms of the GNU Lesser General Public License as published by 30# the Free Software Foundation. A copy of the license agreement is provided 31# in the file named "LICENSE.txt" included with this software distribution 32# and also available online as http://sbml.org/software/libsbml/license.html 33#----------------------------------------------------------------------- -->*/ 34 35use strict; 36use Getopt::Std; 37 38(my $myname = $0) =~ s,.*[\/\\],,; 39my $usage = <<EOF; 40Usage: $myname [-d output_dir] [-h] [-r|-p|-j|-c] ctest_file [ ctest_file2 ... ] 41 -r : Converts given C/C++ test files into Ruby scripts (*Default*) 42 -p : Converts given C/C++ test files into Python scripts 43 -j : Converts given C/C++ test files into Java files 44 -c : Converts given C/C++ test files into C# files 45 46 -o output_dir : converted files will be generated in output_dir 47 48 -d level : turn on debugging with given integer level (1 or 2) 49 -h : print this message 50EOF 51 52my %opts; 53getopts('o:hrpjcd:',\%opts) or die $usage; 54 55my $version = "2009-08-22"; 56 57###################################################################### 58 59my %SBaseClass = ( 60 Compartment => 0, 61 CompartmentType => 0, 62 Constraint => 0, 63 Delay => 0, 64 Event => 0, 65 EventAssignment => 0, 66 FormulaUnitsData => 0, 67 FunctionDefinition => 0, 68 InitialAssignment => 0, 69 KineticLaw => 0, 70 ListOf => 0, 71 ListOfCompartmentTypes => 0, 72 ListOfCompartments => 0, 73 ListOfConstraints => 0, 74 ListOfEventAssignments => 0, 75 ListOfEvents => 0, 76 ListOfFunctionDefinitions => 0, 77 ListOfInitialAssignments => 0, 78 ListOfParameters => 0, 79 ListOfReactions => 0, 80 ListOfRules => 0, 81 ListOfSpecies => 0, 82 ListOfSpeciesReferences => 0, 83 ListOfSpeciesTypes => 0, 84 ListOfUnitDefinitions => 0, 85 ListOfUnits => 0, 86 ModifierSpeciesReference => 0, 87 Model => 0, 88 Parameter => 0, 89 AlgebraicRule => 0, 90 AssignmentRule => 0, 91 RateRule => 0, 92 Rule => 0, 93 Reaction => 0, 94 SBase => 0, 95 SBMLDocument => 0, 96 Species => 0, 97 SpeciesReference => 0, 98 SpeciesType => 0, 99 StoichiometryMath => 0, 100 Trigger => 0, 101 Unit => 0, 102 UnitDefinition => 0, 103# Extensions 104 SBMLExtension => 0, 105# Groups Package 106 Group => 0, 107 Member => 0, 108 GroupsExtension => 0, 109# Layout Package 110 BoundingBox => 0, 111 Point => 0, 112 Dimensions => 0, 113 TextGlyph => 0, 114 SpeciesReferenceGlyph => 0, 115 CubicBezier => 0, 116 SpeciesGlyph => 0, 117 LineSegment => 0, 118 CompartmentGlyph => 0, 119 Layout => 0, 120 Curve => 0, 121 ReactionGlyph => 0, 122 GraphicalObject => 0, 123 ListOfLayouts => 0, 124); 125 126my %MiscClass = ( 127GroupsPkgNamespaces => 0, 128LayoutPkgNamespaces => 0, 129 ASTNode => 0, 130 SBMLReader => 0, 131 SBMLWriter => 0, 132 XMLOutputStream => 0, 133 XMLInputStream => 0, 134 XMLAttributes => 0, 135 XMLNamespaces => 0, 136 XMLTriple => 0, 137 XMLNode => 0, 138 XMLToken => 0, 139 XMLError => 0, 140 SBMLError => 0, 141 CVTerm => 0, 142 ModelHistory => 0, 143 ModelCreator => 0, 144 Date => 0, 145 RDFAnnotationParser => 0, 146 SBMLNamespaces => 0, 147 SyntaxChecker => 0, 148 SBMLTransforms => 0, 149); 150 151my %IgnoredFile = ( 152 TestRunner => 0, 153 TestFormulaParser => 0, 154 TestFormulaFormatter => 0, 155 TestFormulaTokenizer => 0, 156 TestSBMLTransforms => 0, 157 TestSBMLConstructorException => 0, 158 TestXMLErrorLog => 0, 159 TestXMLInputStream => 0, 160 EchoHandler => 0, 161 echoxml => 0, 162); 163 164my %IgnoredClass = ( 165 FormulaUnitsData => 0, 166 XMLErrorLog => 0, 167); 168 169my %IgnoredFunc = ( 170 getNumFormulaUnitsData => 0, 171 addFormulaUnitsData => 0, 172 getInternalId => 0, 173 setInternalId => 0, 174); 175 176my %IgnoreTestFunc = ( 177# groups package 178 test_GroupsExtension_assignment => 0, 179 test_GroupsExtension_SBMLtypecode => 0, 180# layout package 181 test_BoundingBox_assignmentOperator => 0, 182 test_CompartmentGlyph_assignmentOperator => 0, 183 test_CubicBezier_assignmentOperator => 0, 184 test_Curve_assignmentOperator => 0, 185 test_Dimensions_assignmentOperator => 0, 186 test_GraphicalObject_assignmentOperator => 0, 187 test_Layout_assignmentOperator => 0, 188 test_LineSegment_assignmentOperator => 0, 189 test_Point_assignmentOperator => 0, 190 test_ReactionGlyph_assignmentOperator => 0, 191 test_SpeciesGlyph_assignmentOperator => 0, 192 test_SpeciesReferenceGlyph_assignmentOperator => 0, 193 test_TextGlyph_assignmentOperator => 0, 194 test_Curve_createFrom_NULL => 0, 195# sbml core 196 test_ASTNode_getListOfNodes => 0, 197 test_ASTNode_createFromToken => 0, 198 test_XMLOutputStream_createFile => 0, 199 test_XMLOutputStream_createFileWithProgramInfo => 0, 200 test_XMLAttributes_readInto_bool => 0, 201 test_XMLAttributes_readInto_long => 0, 202 test_XMLAttributes_readInto_int => 0, 203 test_XMLAttributes_readInto_double => 0, 204 test_XMLAttributes_create_C => 0, 205 test_XMLAttributes_readInto_uint_C => 0, 206 test_XMLTriple_comparison => 0, 207 test_XMLAttributes_add_removeResource => 0, 208 test_XMLAttributes_readInto_boolean_C => 0, 209 test_XMLAttributes_readInto_double_C => 0, 210 test_XMLAttributes_readInto_long_C => 0, 211 test_XMLAttributes_readInto_int_C => 0, 212 test_XMLAttributes_readInto_string_C => 0, 213 test_XMLErrorLog_create => 0, 214 test_XMLErrorLog_add => 0, 215 test_XMLErrorLog_clear => 0, 216 test_SBML_formulaToString => 0, 217 test_element_semantics => 0, 218 test_element_semantics_URL => 0, 219 test_element_semantics_URL_lambda => 0, 220 test_element_semantics_ann_lambda => 0, 221 test_element_semantics_annotation => 0, 222 test_element_semantics_annxml => 0, 223 test_element_semantics_annxml_lambda => 0, 224 test_element_semantics_lambda => 0, 225 test_MathMLFormatter_semantics => 0, 226 test_MathMLFormatter_semantics_ann => 0, 227 test_MathMLFormatter_semantics_annxml => 0, 228 test_MathMLFormatter_semantics_url => 0, 229 test_MathMLFormatter_ci_definitionURL => 0, 230 test_ASTNode_replaceArgument => 0, 231 test_SBase_addCVTerms_newBag => 0, 232 test_Date_setHoursOffset_neg_arg => 0, 233 test_Date_setOffsetSign => 0, 234 test_Model_copyConstructor => 0, 235 test_Model_assignmentOperator => 0, 236 test_Model_clone => 0, 237 test_Model_add_get_FunctionDefinitions_neg_arg => 0, 238 test_Model_add_get_UnitDefinitions_neg_arg => 0, 239 test_Model_add_get_Event_neg_arg => 0, 240 test_Reaction_removeModifier => 0, 241 test_Reaction_getModifier => 0, 242 test_Reaction_addModifier => 0, 243 test_Reaction_getModifierById => 0, 244 test_SpeciesReference_createModifier => 0, 245 test_Reaction_addModifier1 => 0, 246 test_Reaction_addModifier2 => 0, 247 test_Reaction_addModifier3 => 0, 248 test_Reaction_createModifier => 0, 249 test_Reaction_removeModifier => 0, 250 test_RDFAnnotation_testHasRDFAnnotation => 0, 251 test_RDFAnnotation_testHasAdditionalRDFAnnotation => 0, 252 test_RDFAnnotation_testHasCVTermRDFAnnotation => 0, 253 test_RDFAnnotation_testHasHistoryRDFAnnotation => 0, 254 test_RDFAnnotation_testHasCVTermRDFAnnotationBadAbout => 0, 255 test_RDFAnnotation_testHasHistoryRDFAnnotationBadAbout => 0, 256 test_RDFAnnotation_testCreateAnnotations => 0, 257 test_RDFAnnotation_deleteCVTerms => 0, 258); 259 260###################################################################### 261# Language dependent variables 262###################################################################### 263 264my %ModuleName = ( 265 ruby => 'libSBML', 266 python => 'libsbml', 267 java => 'libsbml', 268 csharp => 'libsbmlcs', 269); 270 271my %Prefix = ( 272 ruby => 'LibSBML::', 273 python => 'libsbml.', 274 java => 'libsbml.', 275 csharp => 'libsbml.', 276); 277 278my %IdNULL = ( 279 ruby => 'nil', 280 python => 'None', 281 java => 'null', 282 csharp => 'null', 283); 284 285my %IdNULLChar = ( 286 ruby => '"\\0"', 287 python => '"\\0"', 288 java => "'\\0'", 289 csharp => "'\\0'", 290); 291 292my %IdTRUE = ( 293 ruby => 'true', 294 python => 'True', 295 java => 'true', 296 csharp => 'true', 297); 298 299my %IdFALSE = ( 300 ruby => 'false', 301 python => 'False', 302 java => 'false', 303 csharp => 'false', 304); 305 306my %IdBOOL = ( 307 java => 'boolean', 308 csharp => 'bool', 309); 310 311my %IdCOUT = ( 312 ruby => 'LibSBML::cout', 313 python => 'libsbml.cout', 314 java => 'libsbml.cout', 315 csharp => 'libsbml.cout', 316); 317 318my %IdOSS = ( 319 ruby => 'oss = LibSBML::Ostringstream.new', 320 python => 'oss = libsbml.ostringstream()', 321 java => 'OStringStream oss = new OStringStream();', 322 csharp => 'OStringStream oss = new OStringStream();', 323); 324 325my %IdSTRING = ( 326 java => 'String', 327 csharp => 'string', 328); 329 330my %constDBL_EPSILON = ( 331 ruby => "\@\@DBL_EPSILON", 332 python => "DBL_EPSILON", 333 java => "DBL_EPSILON", 334 csharp => "DBL_EPSILON", 335); 336 337my %constSBML_INT_MAX = ( 338 ruby => "\@\@SBML_INT_MAX", 339 python => "SBML_INT_MAX", 340 java => "SBML_INT_MAX", 341 csharp => "SBML_INT_MAX", 342); 343 344 345my $JavaPackage = "org.sbml.libsbml.test"; 346my $CSNamespace = "LibSBMLCSTest"; 347 348################################################################### 349 350my $TestDataDirectory = "../../sbml/test/test-data/"; 351 352my $Target = 'ruby'; 353my $OutputDir = '.'; 354 355my %patchGlobal; 356my %patchClassTop; 357my %patchFuncHead; 358my %patchFuncTail; 359my %patchFuncReplace; 360 361my %FuncDef; 362my %MacroDef; 363my %FileProp; 364my %GlobalVariable; 365my %LocalVariable; 366my %TmpLocalVariable; 367 368my %pStatus; 369my $CurFunc; 370my $FlagIfdef; 371my $CurLine; 372my $IsMultiLine; 373my $CurTestDir; 374 375my $Debug = 0; 376 377################################################################### 378# reg-exp 379################################################################### 380# 381# regular expression for nesting parenthesis 382# (reference : Programming Perl 3rd edition) 383# 384my $re_np; 385$re_np = qr{ 386 \( 387 (?: 388 (?> [^()]+ ) 389 | 390 (??{ $re_np }) 391 )* 392 \) 393 }x; 394 395################################################################### 396# main routine 397################################################################### 398 399$opts{'h'} and die $usage; 400$opts{'p'} and $Target = 'python'; 401$opts{'r'} and $Target = 'ruby'; 402$opts{'j'} and $Target = 'java'; 403$opts{'c'} and $Target = 'csharp'; 404$opts{'o'} and $OutputDir = $opts{'o'}; 405 406if ( $opts{'d'} =~ /\d/ ) 407{ 408 $Debug = $opts{'d'}; 409} 410elsif ( $opts{'d'} ) 411{ 412 print "Error: the -d option requires a numerical argument.\n"; 413 die $usage; 414} 415 416&reset(); 417&initPatch(); 418 419INFILES: for my $file (@ARGV) 420{ 421 foreach ( keys %IgnoredFile ) 422 { 423 if ( $file =~ /$_/ ) 424 { 425 print "(ignored) $file\n" ; 426 next INFILES; 427 } 428 } 429 430 if ( $file =~ m| (\w+)/test/ |x ) 431 { 432 $TestDataDirectory = "../../sbml/$1/test/test-data/"; 433 $CurTestDir = $1; 434 } 435 print "\nparsing $file\n\n" if $Debug; 436 &parse($file); 437 &writeCode($file); 438 &reset(); 439} 440 441################################################################### 442# sub routines 443################################################################### 444 445sub reset 446{ 447 %FuncDef = undef; 448 %MacroDef = undef; 449 %FileProp = undef; 450 %pStatus = undef; 451 %GlobalVariable = undef; 452 %LocalVariable = undef; 453 %TmpLocalVariable = undef; 454 $CurFunc = ""; 455 $CurLine = ""; 456 $FlagIfdef = 0; 457 $IsMultiLine = 0; 458 $CurTestDir = 0; 459} 460 461sub getCreateObjString 462{ 463 my ($cname, $arg) = @_; 464 465 my $fcall = ""; 466 467 my $useXMLNS = 0; 468 my $levelversion = 0; 469 470 # skips the third argument in SBMLDocument(level,version,xmlns) 471 if ( defined($SBaseClass{$cname}) ) 472 { 473 my @args = split(",", $arg); 474 if ( scalar(@args) == 3 ) 475 { 476 if ( $args[2] eq "NULL" ) 477 { 478 pop @args if scalar(@args) == 3; 479 $arg = join(",",@args); 480 } 481 else 482 { 483 $useXMLNS = $args[2]; 484 $levelversion = "$args[0],$args[1]"; 485 } 486 } 487 488 } 489 490 ###################################################################### 491 # Ruby 492 ###################################################################### 493 if ( $Target eq 'ruby' ) 494 { 495 if ($useXMLNS) 496 { 497 push (@{$FuncDef{$CurFunc}}, "sbmlns = LibSBML::SBMLNamespaces.new($levelversion)"); 498 push (@{$FuncDef{$CurFunc}}, "sbmlns.addNamespaces($useXMLNS)"); 499 $arg = "sbmlns"; 500 } 501 502 $fcall = "$Prefix{$Target}" . $cname . ".new"; 503 } 504 ###################################################################### 505 # Python 506 ###################################################################### 507 if ( $Target eq 'python' ) 508 { 509 if ($useXMLNS) 510 { 511 push (@{$FuncDef{$CurFunc}}, "sbmlns = libsbml.SBMLNamespaces($levelversion)"); 512 push (@{$FuncDef{$CurFunc}}, "sbmlns.addNamespaces($useXMLNS)"); 513 $arg = "sbmlns"; 514 } 515 516 $fcall = "$Prefix{$Target}" . $cname; 517 } 518 ###################################################################### 519 # Java/C# 520 ###################################################################### 521 if ( ($Target eq 'java') || ($Target eq 'csharp') ) 522 { 523 if ($useXMLNS) 524 { 525 unless ( $TmpLocalVariable{$CurFunc}{"sbmlns"} ) 526 { 527 push (@{$FuncDef{$CurFunc}}, "SBMLNamespaces sbmlns = null;"); 528 $TmpLocalVariable{$CurFunc}{"sbmlns"} = 1; 529 } 530 push (@{$FuncDef{$CurFunc}}, "sbmlns = new SBMLNamespaces($levelversion);"); 531 push (@{$FuncDef{$CurFunc}}, "sbmlns.addNamespaces($useXMLNS);"); 532 $arg = "sbmlns"; 533 } 534 535 $fcall = "new $cname"; 536 } 537 538 539 $fcall .= "(" . $arg . ")"; 540 541 return $fcall; 542} 543 544 545sub getCreateFileString 546{ 547 my ($file) = @_; 548 549 my $fcall = ""; 550 551 ###################################################################### 552 # Ruby 553 ###################################################################### 554 if ( $Target eq 'ruby' ) 555 { 556 $fcall = "$Prefix{$Target}" . "ostream.new"; 557 } 558 ###################################################################### 559 # Python 560 ###################################################################### 561 if ( $Target eq 'python' ) 562 { 563 $fcall = "$Prefix{$Target}" . "createOFStream"; 564 } 565 ###################################################################### 566 # Java/C# 567 ###################################################################### 568 if ( ($Target eq 'java') || ($Target eq 'csharp') ) 569 { 570 $fcall = "new OFStream"; 571 } 572 573 $fcall .= "(" . $file . ")"; 574 575 return $fcall; 576} 577 578 579sub parse 580{ 581 my ($file) = @_; 582 583 (my $file_name = $file) =~ s|.*/||; 584 585 open (FH, $file) or die "Can't open $file : $!/$?"; 586 while (<FH>) 587 { 588 chomp; 589 my $line = $_; 590 $CurLine = $line; 591 $IsMultiLine = 0; 592 593 print "$CurLine\n" if $Debug > 1; 594 595 $line =~ s| /\* .*? \*/ ||xg; 596 597 # 598 # end of comments 599 # 600 if ($pStatus{'inComment'}) 601 { 602 my $code = ""; 603 604 # 605 # coments in header 606 # 607 if ( $line =~ /^ \s* \** \s* [\@\\]brief \s+ (.+) $/x ) 608 { 609 $FileProp{$file_name}{'brief'} = $1; 610 } 611 elsif ( $line =~ /^ \s* \** \s* [\@\\]author \s+ (.+) $/x ) 612 { 613 push ( @{ $FileProp{$file_name}{'author'} } , $1 ); 614 } 615 616 if($line =~ m|\*/(.*)|) 617 { 618 $pStatus{'inComment'} = 0; 619 $code = $1; 620 } 621 else 622 { 623 next; 624 } 625 626 next unless $code; 627 $line = $code; 628 } 629 630 # 631 # start of comments 632 # 633# if ($line =~ m|((.*)/\*|) 634 if ($line =~ m|^ \s* /\* |x) 635 { 636 $pStatus{'inComment'} = 1 unless ($line =~ m|\*/|); 637 next; 638 } 639 # SHOULD BE FIXED 640 elsif ($line =~ m|(.*?) (?<!http:) //|x) 641 { 642 my $substr = $1; 643 next unless $substr; 644 next if ($line =~ m|^ \s* //|x ); 645#print "[CPP Comment] -> $line\n"; 646 if ( $line !~ m| ([\"\']) [^\"\']* // [^\"\']* [\"\'] |x ) 647 { 648 $line = $substr; 649 } 650 } 651 652 # 653 # end of #if... macro 654 # 655 if ($pStatus{'inPPIF'}) 656 { 657 if ( $line =~ / \# \s* endif /x ) 658 { 659 $pStatus{'inPPIF'} = 0; 660 } 661 next; 662 } 663 664 # 665 # start of #if... macro 666 # 667 if ( $line =~ / \# \s* if /x ) 668 { 669 $pStatus{'inPPIF'} = 1; 670 next; 671 } 672 673 # 674 # parsing a setup function 675 # 676 if ($pStatus{'inSETUP'}) 677 { 678 if ($line =~ /^}/) 679 { 680 &parseMisc($line); 681 $pStatus{'inSETUP'} = 0; 682 } 683 else 684 { 685 next if ($line =~ /^\s*$/); 686 print "[call parseMisc] -> $line\n" if $Debug; 687 &parseMisc($line); 688 } 689 } 690 # 691 # parsing a setup function 692 # 693 elsif ($pStatus{'inTEARDOWN'}) 694 { 695 if ($line =~ /^}/) 696 { 697 &parseMisc($line); 698 $pStatus{'inTEARDOWN'} = 0; 699 } 700 else 701 { 702 next if ($line =~ /^\s*$/); 703 print "[call parseMisc] -> $line\n" if $Debug; 704 &parseMisc($line); 705 } 706 } 707 # 708 # parsing a test function 709 # 710 elsif ($pStatus{'inTEST'}) 711 { 712 713 # ignore SBase_getCVTerms 714 #next if ( $line =~ /SBase_getCVTerms/ ); 715 716 717 if ($line =~ /^ \s* END_TEST /x) 718 { 719 $pStatus{'inTEST'} = 0; 720 } 721 elsif ($line =~ /^\s* fail_(?: if | unless) \s* ($re_np) \s*;+\s* $/x ) 722 { 723 my $block = $1; 724 $block =~ s/^\s*\(//; 725 $block =~ s/\)\s*$//; 726 727 # remove ',NULL' from the tail 728 $block =~ s/ , \s* NULL \s* $//x; 729 730 print "[call parseAssertion] -> $block\n" if $Debug; 731#print "[call parseAssertion] -> $block\n"; 732 &parseAssertion($block); 733 } 734 elsif ($line =~ /^ \s* fail_(?: if | unless) \s* \( ( [^;]+ ) /x ) 735 { 736 # 737 # read a next line 738 # 739 my $block = $1; 740# SHOULD BE FIXED 741 $block .= <FH>; 742 chomp $block; 743 # remove ');' from the tail 744 $block =~ s/ \) \s* ;+ \s* $//x; 745 # remove ',NULL' (if any) from the tail 746 $block =~ s/, \s* NULL \s* $//x; 747 $line = $block; 748#print "[misc] -> $block\n"; 749 &parseAssertion($block); 750 } 751 elsif ($line =~ /^\s *fail \s* \( [^;]+ \s* $/x ) 752 { 753 my $block = $line; 754 755 # SHOULD BE FIXED 756 $block .= <FH>; 757 chomp $block; 758 $line = $block; 759 760 &parseMisc($line); 761 } 762 else 763 { 764#print "[call parseMisc] -> $line\n"; 765 766 next if ($line =~ /^\s*$/); 767 768 print "[call parseMisc] -> $line\n" if $Debug; 769 770 my $block = $line; 771 772 # SHOULD BE FIXED 773 # Merge multiple lines (without ';$') into single line. 774 if ( $line !~ /^ \s* ( [\#\{\}] | (if | else \s* if | else) ) /x ) 775 { 776 BLOCK: 777 while( $line !~ /\;+ \s* $/x ) 778 { 779 $line = <FH>; 780 chomp $line; 781 $line =~ s/^\s*//; 782 783#print "[call parseMisc (while)] $line \n"; 784 785 if ( $line =~ /\;+ \s* $/x ) 786 { 787 #$block =~ s/\+ (\s*?) $/$1/x; 788 if ( $line !~ /^ \s* " (?:[^"]|\\")*? (?<!\\) "/x 789 && $line !~ /^ \s* ' (?:[^']|\\')*? (?<!\\) '/x 790 ) 791 { 792 $block =~ s/\+ (\s*) \z/$1/x; 793 } 794 elsif ( ( $line !~ /\s+ = \s+/x ) && ( $block !~ / \+ \s* $/x ) ) 795 { 796 $line = " + " . $line; 797 } 798 799 chomp $block; 800 $block .= $line; 801 last BLOCK; 802 } 803 elsif ( $line =~ /^ \s* " (?:[^"]|\\")*? (?<!\\) " \s* $/x ) 804 { 805 $line = $line . " + " . "\n "; 806 } 807 elsif ( $line =~ /^ \s* ' (?:[^']|\\')*? (?<!\\) ' \s* $/x ) 808 { 809 $line = $line . " + " . "\n "; 810 } 811 812 $block .= $line; 813 $IsMultiLine = 1; 814 } 815#print "[call parseMisc (multiple)] $line -> $block\n"; 816 } 817 &parseMisc($block); 818 } 819 } 820 else 821 { 822 # 823 # start of a setup function found 824 # 825 if ($line =~ /_setup \w? \s* \(.*\)/x) 826 { 827 $pStatus{'inSETUP'} = 1; 828 ################################################## 829 # Ruby 830 ################################################## 831 if ( $Target eq 'ruby' ) 832 { 833 $CurFunc = "setup"; 834 } 835 ################################################## 836 # Python 837 ################################################## 838 elsif ( $Target eq 'python' ) 839 { 840 $CurFunc = "setUp"; 841 } 842 ################################################## 843 # Java 844 ################################################## 845 elsif ( $Target eq 'java' ) 846 { 847 $CurFunc = "protected void setUp() throws Exception"; 848 } 849 ################################################## 850 # C# 851 ################################################## 852 elsif ( $Target eq 'csharp' ) 853 { 854 $CurFunc = "setUp"; 855 } 856 857 } 858 # 859 # start of teardown function found 860 # 861 elsif ($line =~ /_teardown \w? \s* \(.*\)/x) 862 { 863 $pStatus{'inTEARDOWN'} = 1; 864 ################################################## 865 # Ruby 866 ################################################## 867 if ( $Target eq 'ruby' ) 868 { 869 $CurFunc = "teardown"; 870 } 871 ################################################## 872 # Python 873 ################################################## 874 elsif ( $Target eq 'python' ) 875 { 876 $CurFunc = "tearDown"; 877 } 878 ################################################## 879 # Java 880 ################################################## 881 elsif ( $Target eq 'java' ) 882 { 883 $CurFunc = "protected void tearDown() throws Exception"; 884 } 885 ################################################## 886 # C# 887 ################################################## 888 elsif ( $Target eq 'csharp' ) 889 { 890 $CurFunc = "tearDown"; 891 } 892 893 } 894 # 895 # start of a test function 896 # 897 elsif ($line =~ /^ \s* START_TEST \s* \( \s* (\w+) \s* \)/x ) 898 { 899 $pStatus{'inTEST'} = 1; 900 $CurFunc = $1; 901 } 902 # 903 # macro definition 904 # 905 elsif ($line =~ /^\s* \#define/x ) 906 { 907 &parseMisc($line); 908 } 909 # 910 # global variable 911 # 912 elsif ( $line =~ /^ (?: static \s* )? (?: (?: const | unsigned ) \s*)? \s* ( \w+ ) \s* \*? \s* (\w+) \s*\;+\s* $/x ) 913 { 914 my $type = $1; 915 my $var = $2; 916 next if $1 =~ /return/; 917 918 print "[global variable] $2\n" if $Debug; 919 920 ################################################## 921 # Ruby/Python 922 ################################################## 923 if ( ( $Target eq 'ruby' ) || ( $Target eq 'python') ) 924 { 925 $GlobalVariable{$var} = 1; 926 } 927 ################################################## 928 # Java / C# 929 ################################################## 930 elsif ( ( $Target eq 'java' ) || ( $Target eq 'csharp') ){ 931 932#print "[global variable] $CurLine\n"; 933 if ( $CurLine =~ /^ \s* \w*? \s* SpeciesReference .* (?: _createModifier | MSR )/x ) 934 { 935 $type =~ s/^\s* (\w*?) \s* SpeciesReference_t/$1 SimpleSpeciesReference/x; 936 } 937 $type =~ s/_t$//; 938 $type =~ s/^char$/$IdSTRING{$Target}/x; 939 $type =~ s/^ostringstream$/OStringStream/; 940 $GlobalVariable{"$type $var"} = 1; 941#print "[global variable] $type\n"; 942 } 943 } 944 else{ 945#print "[ignored variable] $line\n"; 946 } 947 } 948 } 949 close(FH); 950} 951 952sub parseAssertion 953{ 954 my ($line) = @_; 955 956 print "[parseAssertion(top)] -> $line\n" if $Debug; 957 958 $line =~ s/ numeric_limits \s* < \s* double \s* > \s* ::infinity \s* $re_np /util_PosInf\(\)/x ; 959 960 if ( $line =~ /^ \s* 961 ( (?: (?: (?<!\\) " (?:[^"]|\\")*? (?<!\\) " | (?<!\\) ' (?:[^']|\\')*? (?<!\\) ') | [^"'] )* ) 962 (?<=\w|["')]|\s) ( == | < | > | != | >= | <= ) (?=\w|[("'*]|\s) 963 ( (?: (?: (?<!\\) " (?:[^"]|\\")*? (?<!\\) " | (?<!\\) ' (?:[^']|\\')*? (?<!\\) ') | [^"'] )* ) 964 \s* $ 965 /x 966 ) 967 { 968 print "[parseAssertion(before)] $1 $2 $3\n" if $Debug; 969 970 my $b1 = $1; 971 my $b2 = $2; 972 my $b3 = $3; 973 974 print "b1 = $b1\n" if $Debug > 2; 975 print "b2 = $b2\n" if $Debug > 2; 976 print "b3 = $b3\n" if $Debug > 2; 977 978 my @block = &parseBlock($b1); 979 my $left = join('',@block); 980 981 my $op = $b2; 982 983 @block = &parseBlock($b3); 984 my $right = join('',@block); 985 986 print "b3 after parseBlock = $right\n" if $Debug > 2; 987 988 # 989 # Ignored functions 990 # 991 if ( ($left eq "") or ($right eq "") ) 992 { 993 { 994 print "(IGNORED) [parseAssertion] $left $op $right \n" if $Debug > 2; 995 return; 996 } 997 } 998 999 if ( ($left =~ /copy\.getName\(\)/ ) or ($right =~ /copy\.getName\(\)/) ) 1000 { 1001 { 1002 print "(IGNORED) [parseAssertion] $left $op $right \n" if $Debug > 2; 1003 return; 1004 } 1005 } 1006 1007 my $prexp = ""; 1008 1009 ###################################################################### 1010 # Java/C# 1011 ###################################################################### 1012 if ( ($Target eq 'java') || ($Target eq 'csharp') ) 1013 { 1014 $prexp = qr{ \s* $re_np \s* $ }x; 1015 } 1016 1017 if ( $b1 =~ /strcmp/ ) 1018 { 1019 $right = $IdFALSE{$Target} if $right eq '0'; 1020 $right = $IdTRUE{$Target} if $right eq '1'; 1021 } 1022 elsif ( $left =~ / 1023 (?: 1024 1025 (?: 1026 isSet( 1027 ModelHistory 1028 |Id 1029 |Formula 1030 |InitialAmount 1031 |InitialConcentration 1032 |Message 1033 |KineticLaw 1034 |Annotation 1035 |Notes 1036 |Value 1037 |Charge 1038 |Math 1039 |Constant 1040 |Fast 1041 |Reversible 1042 |UseValuesFromTriggerTime 1043 |BoundaryCondition 1044 |HasOnlySubstanceUnits 1045 |Units 1046 ) 1047 ) 1048 1049 | 1050 1051 (?: 1052 setLevelAndVersion 1053 ) 1054 1055 | 1056 1057 (?: 1058 get( 1059 Fast 1060 |Reversible 1061 |BoundaryCondition 1062 |Constant 1063 |HasOnlySubstanceUnits 1064 |ContainsUndeclaredUnits 1065 |CanIgnoreUndeclaredUnits 1066 |UseValuesFromTriggerTime 1067 ) 1068 ) 1069 1070 | 1071 1072 (?: 1073 containsUndeclaredUnits 1074 ) 1075 1076 | 1077 1078 (?: 1079 is( 1080 Sqrt 1081 |Log10 1082 |UMinus 1083 |Empty 1084 |End 1085 |EOF 1086 |Info 1087 |Warning 1088 |Error 1089 |Fatal 1090 |Good 1091 |AttributesEmpty 1092 |NamespacesEmpty 1093 |Element 1094 |Text 1095 |Start 1096 |SetFamilyName 1097 |SetGivenName 1098 |SetEmail 1099 |SetOrganisation 1100 |SetOrganization 1101 |SetCreatedDate 1102 |SetModifiedDate 1103 ) 1104 ) 1105 1106 | 1107 1108 (?: 1109 has( Attribute | URI | NS | Prefix | Attr | Namespace(?:URI|NS|Prefix) ) 1110 ) 1111 1112 | 1113 1114 (?: 1115 util_isInf 1116 ) 1117 1118 ) $prexp 1119 /x 1120 ) 1121 { 1122 $right = $IdFALSE{$Target} if $right eq '0'; 1123 $right = $IdTRUE{$Target} if $right eq '1'; 1124 } 1125 elsif ( $CurLine =~ /ASTNode_getCharacter \s* $re_np /x 1126 && $left =~ /getCharacter /x ) 1127 { 1128 $right =~ s/^\s+//; 1129 $right =~ s/\s+$//; 1130 $right = $IdNULLChar{$Target} if ( $right eq '0' || $right eq "'\\0'" ); 1131 } 1132 elsif ( $left =~ / (?: getModel | getNamespaces ) \s* $re_np /x ) 1133 { 1134 $right = $IdNULL{$Target} if $right eq '0'; 1135 } 1136 elsif ( $CurLine =~ /ASTNode_getName \s* $re_np /x 1137 && $left =~ /getName /x ) 1138 { 1139 $right = $IdNULL{$Target} if ( $right eq "" || $right eq '0' ); 1140 } 1141 elsif ( $CurLine !~ /Constraint_getMessage/ && 1142 $left =~ /get( 1143 MetaId 1144 |Id 1145 |Name 1146 |Formula 1147 |Variable 1148 |TimeUnits 1149 |Units 1150 |Outside 1151 |Symbol 1152 |SubstanceUnits 1153 |Species 1154 |Compartment 1155 |SpatialSizeUnits 1156 |URI 1157 |Prefix 1158 |Index 1159 |AttrValue 1160 |AttrPrefix 1161 |AttrURI 1162 |NamespaceIndex 1163 |Message 1164 |SeverityAsString 1165 |CategoryAsString 1166 |SBOTermID 1167 |ConversionFactor 1168 |VolumeUnits 1169 |AreaUnits 1170 |LengthUnits 1171 ) $prexp 1172 /x 1173 ) 1174 { 1175 1176 if ($right eq $IdNULL{$Target} ) 1177 { 1178 if ( $line !~ /Model_get(Species|Compartment)/x ) 1179 { 1180 ###################################################################### 1181 # Python/Ruby/C# 1182 ###################################################################### 1183 if ( ($Target eq 'python') || ($Target eq 'ruby') || ($Target eq 'csharp') ) 1184 { 1185 $right = '""'; 1186 } 1187 ###################################################################### 1188 # Java 1189 ###################################################################### 1190 elsif ( $Target eq 'java' ) 1191 { 1192 $right = "true"; 1193 $left .= '.equals("")'; 1194 } 1195 } 1196 } 1197 ###################################################################### 1198 # Java 1199 ###################################################################### 1200 elsif ( $Target eq 'java' ) 1201 { 1202 unless ( $right =~ /^ \s* (?: 1203 \-?(\d*\.)?\d+ 1204 | 1205 libsbml\..+ 1206 | 1207 true 1208 | 1209 false 1210 | 1211 null 1212 | 1213 '.*' 1214 | 1215 ".*" 1216 ) \s* $/x 1217 ) 1218 { 1219 $left .= ".equals(${right})"; 1220 $right = "true"; 1221 } 1222 } 1223 1224 } 1225 ###################################################################### 1226 # Python 1227 ###################################################################### 1228 elsif ( ($Target eq 'python') 1229 && 1230 $left =~ / get(?: Event | FunctionDefinition | UnitDefinition ) /x ) 1231 { 1232 # In Python, 'int' can't be passed to where 'unsigned int' required 1233 $left =~ s/ ( \- [0-9]+ ) \s* \) \s*$/99999)/x ; 1234 } 1235 ###################################################################### 1236 # Java/C# 1237 ###################################################################### 1238 elsif ( ( ($Target eq 'java') || ($Target eq 'csharp') ) 1239 && 1240 $left =~ / get(\w+) $prexp /x ) 1241 { 1242 my $cname = $1; 1243 $cname =~ s/By.*?//; 1244 if ( defined($SBaseClass{$cname}) || ($cname eq 'Modifier') 1245 || ($cname eq 'Product') || ($cname eq 'Reactant')) 1246 { 1247 my $fcall; 1248 if ($op eq '==') 1249 { 1250 $fcall = "assertEquals("; 1251 } 1252 elsif ($op eq '!=') 1253 { 1254 $fcall = "assertNotEquals("; 1255 } 1256 $fcall .= "$left,$right);"; 1257 push (@{$FuncDef{$CurFunc}}, $fcall); 1258 return; 1259 } 1260 } 1261 1262 ###################################################################### 1263 1264 print "[parseAssertion(after)] -> $left $op $right\n" if $Debug; 1265 push (@{$FuncDef{$CurFunc}}, &addAssertion2($left,$right,$op)); 1266 1267 } 1268 elsif ($line =~ /^ \s* !? \s* strcmp/x ) 1269 { 1270# push (@{$FuncDef{$CurFunc}}, &parseBlock($line)); 1271 ################################################## 1272 # Ruby 1273 ################################################## 1274 if ( $Target eq 'ruby') 1275 { 1276 push (@{$FuncDef{$CurFunc}}, "assert (" . &parseBlock($line) . ")"); 1277 } 1278 ################################################## 1279 # Python 1280 ################################################## 1281 elsif ( $Target eq 'python') 1282 { 1283 push (@{$FuncDef{$CurFunc}}, "self.assert_(" . &parseBlock($line) . ")"); 1284 } 1285 ################################################## 1286 # Java / C# 1287 ################################################## 1288 elsif ( ( $Target eq 'java') || ( $Target eq 'csharp') ) 1289 { 1290 push (@{$FuncDef{$CurFunc}}, "assertTrue(" . &parseBlock($line) . ");"); 1291 } 1292 ################################################## 1293 } 1294 else 1295 { 1296#print "[In parseAssertion(three before)] -> $line\n"; 1297 my $bool_flag = 1; 1298 1299 $bool_flag = 0 if ($line =~ s/^ \s* !//x); 1300 1301 my $one = &parseBlock($line); 1302 1303 push (@{$FuncDef{$CurFunc}}, &addAssertion1($one,$bool_flag)); 1304 } 1305 1306} 1307 1308sub parseMisc 1309{ 1310 my ($line) = @_; 1311 1312 print "[parseMisc (before)] $line\n" if $Debug > 1; 1313 1314# SHOULD BE FIXED 1315# return if ($line =~ /_free\(.+\)/); 1316 1317 my @block = &parseBlock($line); 1318 my $block = join('',@block); 1319 1320 print "[parseMisc (after) ] $line -> $block\n" if $Debug > 1; 1321 1322 next if $block =~ /^\s*$/; 1323 1324 # variable definition only 1325 return if ($block =~ /^[_a-zA-Z0-9]+$/); 1326 1327 if ( $block =~ /^ \s* \#ifdef \s* ( USE_(?: LIBXML | EXPAT | XERCES) )/x ) 1328 { 1329 my $val = $1; 1330 ###################################################################### 1331 # Ruby 1332 ###################################################################### 1333 if ( $Target eq 'ruby' ) 1334 { 1335 $block = "if ( \@\@$val == 1 )"; 1336 } 1337 ###################################################################### 1338 # Python 1339 ###################################################################### 1340 elsif ( $Target eq 'python' ) 1341 { 1342 $block = "if $val == 1 "; 1343 } 1344 ###################################################################### 1345 # Java / C# 1346 ###################################################################### 1347 elsif ( ( $Target eq 'java' ) || ( $Target eq 'csharp' ) ) 1348 { 1349 $block = "if ( $val == 1 )"; 1350 } 1351 1352 push (@{$FuncDef{$CurFunc}}, $block); 1353 $block = "{"; 1354 1355 $FlagIfdef = 1; 1356 } 1357 elsif ( $block =~ /^ \s* \#endif /x ) 1358 { 1359 if ( $FlagIfdef ){ 1360 $block = "}"; 1361 $FlagIfdef = 0; 1362 } 1363 } 1364 else 1365 { 1366 ###################################################################### 1367 # Java / C# 1368 ###################################################################### 1369 if ( ( $Target eq 'java' ) || ( $Target eq 'csharp' ) ) 1370 { 1371 if ($block !~ /\s* \;+ \s*$/x ) 1372 { 1373 $block .= ";" unless $block =~ /[{}]\s*$/x; 1374 } 1375 } 1376 } 1377 1378 1379#print "[parseMisc ] $line -> $block\n"; 1380 1381 push (@{$FuncDef{$CurFunc}}, $block); 1382} 1383 1384 1385sub parseBlock 1386{ 1387 my ($line) = @_; 1388 1389 return "" if ( $line =~ /^ \s* for \s* \(/x ); 1390 1391 print "[parseBlock (top)] $line\n" if $Debug > 1; 1392 1393 ###################################################################### 1394 1395 if ( ( $Target eq 'python' ) || ($Target eq 'ruby') ) 1396 { 1397 # remove static_cast<...>( ) and const_cast<...>() 1398 $line =~ s{ 1399 (?:static|const|dynamic)_cast\s*< \s* \w+? \s* \*? \s*> \s* ($re_np) 1400 } 1401 { 1402 (my $r = $1) =~ s,(?:^\(|\)$),,g; 1403 $r; 1404 }xe; 1405 1406 # remove cast 1407 $line =~ s/^\s* \(\s* [a-zA-Z_]+ \s* \* \s* \) \s*//x; 1408 } 1409 else 1410 { 1411 # SHOULD BE FIXED 1412 1413 my $innertype; 1414 $line =~ s{ 1415 (?:static|const|dynamic)_cast\s*< \s* ( \w+? ) \s* \*? \s*> \s* ($re_np) 1416 } 1417 { 1418 $innertype = $1; 1419 (my $r = $2) =~ s,(?:^\(|\)$),,g; 1420 "(($innertype) $r)"; 1421 }xe; 1422 if ( $Target eq 'java') 1423 { 1424 $line =~ s/->clone \s* \(/.cloneObject\(/x; 1425 } 1426 $line =~ s/-> \s* (\w)/.$1/x; 1427 # remove cast 1428 $line =~ s/^\s* \(\s* [a-zA-Z_]+ \s* \* \s* \) \s*//x; 1429 1430 if ( $line =~ /setValue/ and $innertype =~ /long/ ) 1431 { 1432 # This should be handled in a better way, but I can't come up with 1433 # one now. Calls to ASTNode setValue, if the first argument is 1434 # cast to long (instead of int), will be mapped to the wrong 1435 # setValue() variant by Java. 1436 1437 $line =~ s/long/int/; 1438 } 1439 } 1440 1441 if ( $Target eq 'csharp' ) 1442 { 1443 $line =~ s/\b(object)\b/object1/x; 1444 } 1445 1446 # remove 'std::' 1447 $line =~ s/^\s* std::nothrow//x; 1448 $line =~ s/^\s* std:://x; 1449 1450 # util_PosInf(), util_NegInf(), util_NaN() 1451 return $line if ( $line =~ /^ \s* util_(PosInf|NegInf|NaN) \s* \( \s* \) \s* $/x ); 1452 1453 $line =~ s/ numeric_limits \s* < \s* double \s* > \s* :: \s* infinity \s* $re_np /util_PosInf\(\)/x ; 1454 $line =~ s/ numeric_limits \s* < \s* double \s* > \s* :: \s* quiet_NaN \s* $re_np /util_NaN\(\)/x ; 1455 1456 # string "..." 1457 return $line if ($line =~ /^ \s* " (?:[^"]|\\")*? (?<!\\) " \s* ;* \s* $/x); 1458 # string '...' 1459 return $line if ($line =~ /^ \s* ' (?:[^']|\\')*? (?<!\\) ' \s* ;* \s* $/x); 1460 1461 # ModelHistory::getListCreators()->get(...) -> ModelHistory::getCreator(..) 1462 $line =~ s/ getListCreators\(\)->get /getCreator/gx; 1463 1464 # "(...);" -> "..." 1465 $line =~ s/^ \s* \( (.*) \) \s* \; \s* $/$1/x; 1466 1467 ############################################################################### 1468 # 1469 # macro definition 1470 # 1471 # (Pattern 1) #define DEFINITION 1472 # 1473 ############################################################################### 1474 if ( $line =~ /^ \s* \#define \s* (.*) /x ) 1475 { 1476 print "parseBlock(pattern 1) $line -> $1\n" if $Debug > 2; 1477 1478 my $macro_def = &convertMacroDefine($1); 1479 1480 return $macro_def; 1481 } 1482 ############################################################################### 1483 # 1484 # if/else if 1485 # 1486 # (Pattern 2) if (...) | if (...) { | else if (...) | else if (...) { 1487 # 1488 ############################################################################### 1489 elsif( $line =~ /^ \s* (if|else if) \s* ($re_np) \s* ( {? ) \s* $/x ) 1490 { 1491 print "parseBlock(pattern 2) $line -> $1 $2 $3\n" if $Debug > 2; 1492 1493 my $b1 = $1; 1494 my $b2 = $2; 1495 my $b3 = $3; 1496 1497 $b2 =~ s/^\(//; 1498 $b2 =~ s/\)$//; 1499 1500 $b2 = &parseBlock($b2); 1501 1502 # SHOULD BE FIXED 1503 1504 return $b1 . " (" . $b2 . ")" . $b3; 1505 } 1506 ############################################################################### 1507 # 1508 # operators 1509 # 1510 # (Pattern 3) LEFTBLOCK (= | == | != | < | > | >= | <= ) RIGHTBLOCK 1511 # 1512 ############################################################################### 1513 elsif ( $line =~ /^ \s* 1514 ( (?: (?: (?<!\\) " (?:[^"]|\\")*? (?<!\\) " | (?<!\\) ' (?:[^']|\\')*? (?<!\\) ') | [^"'] )* ) 1515 (?<=\w|["')]|\s) ( = | == | < | > | != | >= | <= ) (?=\w|[("'*]|\s) 1516 ( (?: (?: (?<!\\) " (?:[^"]|\\")*? (?<!\\) " | (?<!\\) ' (?:[^']|\\')*? (?<!\\) ') | [^"'] )* ) 1517 \s* $ 1518 /x 1519 ) 1520 { 1521 my $b1 = $1; 1522 my $c1 = $2; 1523 my $b2 = $3; 1524 1525 print "[parseBlock (pattern 3)] $b1 || $c1 || $b2\n" if $Debug > 2; 1526 1527 print "[parseBlock left ...]\n" if $Debug > 2; 1528 my $left = &parseBlock($b1, 1); 1529 1530 print "[parseBlock right ...]\n" if $Debug > 2; 1531 my $right = &parseBlock($b2, 1); 1532 1533 print "[parseBlock (operator)] $left || $right\n" if $Debug > 2; 1534 1535 if ( ($left eq "") or ($right eq "") ) 1536 { 1537 print "(IGNORED) [parseBlock (operator)] $b1 $c1 $b2 (left) $left (right) $right \n" if $Debug > 2; 1538 return ""; 1539 } 1540 1541 print "$b2 -> $right\n" if $b2 =~ /X0/ and $Debug > 2; 1542 print "$b2 -> $right\n" if $b2 =~ /wrap/ and $Debug > 2; 1543 1544 if ( ( $Target eq 'java' ) || ($Target eq 'csharp')) 1545 { 1546 $right .= ";" if $line =~ /^ \s* \;+ \s* $/x; 1547 } 1548 1549 1550 if ( $IsMultiLine ) 1551 { 1552 if ($right =~ /^ \s* [\"\'] .+ [\"\'] \s* \;* \s* $/xs ) 1553 { 1554 print "[RIGHT] $right\n" if $Debug > 2; 1555 $right =~ s| \\n \" \" |\\n" + "|xs; 1556 if ( $Target eq 'python' ) 1557 { 1558 $right =~ s/\;* \s* $//sx; 1559 $right = "wrapString(" . $right . ")"; 1560 } 1561 } 1562 } 1563 1564 1565 return $left . " $c1 " . $right; 1566 } 1567 ############################################################################### 1568 # 1569 # SBASE_FUNC (C) 1570 # 1571 # (Pattern 4) CNAME_FNAME (..) | CNAME_FNAME (..) ; | ! CNAME_FNAME (..) | ! CNAME_FNAME (..) ; 1572 # 1573 ############################################################################### 1574 elsif( $line =~ /^ \s* ( !? \s* [A-Z]\w+? )_( \w+? ) \s* ($re_np) \s* ;* \s* $/x) 1575 { 1576 print "[parseBlock (pattern 4)] -> $1 $2 $3\n" if $Debug > 1; 1577 print "[SBaseFunc] $1 $2 $3\n" if $Debug > 2; 1578 print "[SBaseFunc] $line -> $1 $2 $3\n" if $Debug > 2; 1579 1580 my $cname = $1; 1581 my $fname = $2; 1582 my $args = $3; 1583 1584 $args =~ s/^\(//; 1585 $args =~ s/\)$//; 1586 1587 print "args reinterpreted as: $args\n" if $Debug > 2; 1588 my @args = &parseBlock($args); 1589 1590 if ($cname eq 'SBMLTypeCode' ) 1591 { 1592 return "$Prefix{$Target}${cname}_${fname}(@args)"; 1593 } 1594 1595 print "[SBaseFunc (parse) ] $cname $fname @args \n" if $Debug > 2; 1596 1597 return &convertSBaseCFuncCall($cname,$fname,@args); 1598 } 1599 ############################################################################### 1600 # 1601 # MISC_CFUNC (or CPP constructer) 1602 # 1603 # (Pattern 5) FNAME (..) | FNAME (..) ; | ! FNAME (..) | ! FNAME (..) ; 1604 # 1605 ############################################################################### 1606 elsif( $line =~ /^ \s* ( !? \s* \w+ ) \s* ($re_np) \s* ;* \s* $/x) 1607 { 1608 print "[parseblock (pattern 5)] line $line\n" if $Debug > 1; 1609 1610 # general methods 1611 my $fname = $1; 1612 my $args = $2; 1613 $args =~ s/^\(//; 1614 $args =~ s/\)$//; 1615 my @args = &parseBlock($args); 1616 1617 print "[MiscFunc (parse) ] $fname || @args \n" if $Debug > 1; 1618 1619 my $fcall; 1620 1621 if ( defined( $SBaseClass{$fname} ) || defined( $MiscClass{$fname} ) ) 1622 { 1623 print "[MiscFunc C++ constructor (parse) ] $fname || @args \n"if $Debug > 2; 1624 $fcall = &convertCPPNew($fname, @args); 1625 } 1626 else 1627 { 1628 print "[MiscFunc C function (parse) ] $fname || @args \n"if $Debug > 2; 1629 $fcall = &convertCFuncCall($fname,@args); 1630 } 1631 1632 return $fcall; 1633 } 1634 ############################################################################### 1635 # MISC_CPPFUNC 1636 # 1637 # (Pattern 6) ( OBJ->FNAME(..) | OBJ.FNAME(..) | CNAME::FNAME(..) 1638 # 1639 ############################################################################### 1640 elsif( $line =~ /^ \s* ( !? (?: \( \w+? \s* \*? \s* \) )? \s* (?:\w+)? ) (->|\.|::) (\w+) \s* ($re_np) \s* 1641 ((?:(?:->|\.)\w+\s*$re_np )*) 1642 \s*;*\s* $/x 1643 ) 1644 { 1645 print "[parseblock (Pattern 6)] line $line\n" if $Debug > 1; 1646 1647 # general methods 1648 my $obj = $1; 1649 my $asymbol = $2; 1650 1651 my $fname = $3; 1652 my $args = $4; 1653 my $rest = $5; 1654 1655 print "[CPPFunc] obj $obj asymbol $asymbol fname $fname args $args rest $rest\n" if $Debug > 2; 1656 1657 # 1658 # ignored functions 1659 # 1660 return "" if $fname =~ /^c_str$/; 1661 foreach ( keys %IgnoredFunc ) 1662 { 1663 if ( $fname =~ /$_/ ) 1664 { 1665 print "(IGNORED) [CPPFunc] $line \n" if $Debug > 2; 1666 return; 1667 } 1668 } 1669 1670 $args =~ s/^\(//; 1671 $args =~ s/\)$//; 1672 1673 my @args = &parseBlock($args); 1674 $args = join(',',@args); 1675 1676 my @rest = &parseBlock($rest); 1677 $rest = join(',',@rest); 1678 1679 # static function 1680 $asymbol = "." if $asymbol =~ "::"; 1681 1682 ################################################## 1683 # Python 1684 ################################################## 1685 if ( $Target eq 'python' ) 1686 { 1687 my $val = $1 if $obj =~ /(\w+)/ ; 1688 $obj = "self.${obj}" if ( defined( $GlobalVariable{$val} ) ); 1689 } 1690 1691 ################################################## 1692 # Python/Ruby 1693 ################################################## 1694 if ( $Target eq 'ruby' ) 1695 { 1696 my $val = $1 if $obj =~ /(\w+)/ ; 1697 $obj = "@@" . lc${obj} if ( defined( $GlobalVariable{$val} ) ); 1698 } 1699 if ( ( $Target eq 'python' ) || ( $Target eq 'ruby') ) 1700 { 1701 $obj = "$Prefix{$Target}${obj}" if ( defined( $SBaseClass{$obj} ) || defined( $MiscClass{$obj}) ); 1702 } 1703 ################################################## 1704 1705 my $fcall = $obj . $asymbol . $fname . "(" . $args . ")" . $rest; 1706 1707 return &convertCPPFuncCall($fcall); 1708 } 1709 ############################################################################### 1710 # 1711 # new 1712 # 1713 # (Pattern 7) new CNAME (...) ; | new CNAME (...) 1714 # 1715 ############################################################################### 1716 elsif( $line =~ /^ \s* new \s* (?:$re_np)? \s+ (\w+) \s* ( (?:$re_np)? ) \s* ;* \s* $/x) 1717 { 1718 my $cname = $1; 1719 my $args = $2; 1720 1721 print "[parseBlock (pattern 7)] $cname $args\n" if $Debug > 1; 1722 1723 $args =~ s/^\s*\(//; 1724 $args =~ s/\)\s*$//; 1725 1726 print "[parseBlock (pattern 7)] cname $cname args $args : (CurLine) $CurLine\n" if $Debug > 2; 1727 1728 my @args = &parseBlock($args); 1729 1730 my $fcall = ""; 1731 1732 print "[CPPNew (args) ] cname $cname args @args\n" if $Debug > 2; 1733 1734 $fcall = &convertCPPNew($cname, @args); 1735 1736 return $fcall; 1737 } 1738 ############################################################################### 1739 # 1740 # C++ constructor 1741 # 1742 # (Pattern 8) CNAME variable (...) ; 1743 # 1744 ############################################################################### 1745 elsif( $line =~ /^ \s* (\w+) \s* (\w+) \s* ($re_np) \s* ;+ \s* $/x) 1746 { 1747 my $cname = $1; 1748 my $val = $2; 1749 my $args = $3; 1750 my $fcall = ""; 1751 1752 print "[parseBlock (pattern 8)] cname $cname val $val args \n" if $Debug > 2; 1753 1754 $args =~ s/^\s*\(//; 1755 $args =~ s/\)\s*$//; 1756 1757 my @arg = &parseBlock($args); 1758 $args = join(',',@arg); 1759 1760 if ( defined( $IgnoredClass{$cname} ) ) 1761 { 1762 print "(IGNORED) [CPP Constructer (args) ] cname $cname val $val\n" if $Debug > 2; 1763 $LocalVariable{$CurFunc}{$val} = 0; 1764 # ignored 1765 } 1766 elsif ( defined( $SBaseClass{$cname} ) || defined( $MiscClass{$cname}) ) 1767 { 1768 return "" if ( $cname eq "Rule" ); 1769 ################################################## 1770 # Ruby 1771 ################################################## 1772 if ( $Target eq 'ruby' ) 1773 { 1774 $fcall = "$val = " . $Prefix{'ruby'} . $cname . ".new( $args )"; 1775 } 1776 ################################################## 1777 # Python 1778 ################################################## 1779 elsif ( $Target eq 'python' ) 1780 { 1781 $fcall = "$val = " . $Prefix{'python'} . $cname . "( $args )"; 1782 } 1783 ################################################## 1784 # Java / C# 1785 ################################################## 1786 elsif ( ( $Target eq 'java' ) || ( $Target eq 'csharp' ) ) 1787 { 1788 $fcall = "$cname $val = new $cname ( $args );"; 1789 } 1790 ################################################## 1791 } 1792 elsif ( $cname eq 'string' ) 1793 { 1794 if ($args eq 'TestDataDirectory') 1795 { 1796 $args = "\"$TestDataDirectory\""; 1797 1798 ################################################## 1799 # Ruby/Python 1800 ################################################## 1801 if ( ( $Target eq 'ruby' ) || ( $Target eq 'python' ) ) 1802 { 1803 $fcall = "$val = $args"; 1804 } 1805 ################################################## 1806 # Java 1807 ################################################## 1808 elsif ($Target eq 'java') 1809 { 1810 $fcall = "$IdSTRING{$Target} $val = new $IdSTRING{$Target}( $args );"; 1811 } 1812 ################################################## 1813 # C# 1814 ################################################## 1815 elsif ($Target eq 'csharp') 1816 { 1817 $fcall = "$IdSTRING{$Target} $val = $args;"; 1818 } 1819 1820 } 1821 } 1822 1823 return $fcall; 1824 } 1825 1826 ############################################################################### 1827 # 1828 # operators 1829 # 1830 # (Pattern 8.5) LEFTBLOCK (- | + | * | / | % ) RIGHTBLOCK 1831 # 1832 ############################################################################### 1833 elsif ( $line =~ /^ \s* 1834 ( (?: (?: (?<!\\) " (?:[^"]|\\")+? (?<!\\) " | (?<!\\) ' (?:[^']|\\')+? (?<!\\) ') | [^"' ] )+ ) 1835 \s* (?<=\w|["')]|\s) (?<!\,\s|\de|\dE) ( \- | \+ | \/ | \% ) (?=\w|[("'*]|\s) \s* 1836 ( (?: (?: (?<!\\) " (?:[^"]|\\")+? (?<!\\) " | (?<!\\) ' (?:[^']|\\')+? (?<!\\) ') | [^"' ] )+ ) 1837 \s* $ 1838 /x 1839 ) 1840 { 1841 my $b1 = $1; 1842 my $c1 = $2; 1843 my $b2 = $3; 1844 1845 print "[parseBlock (pattern 8.5)] $b1 || $c1 || $b2\n" if $Debug > 2; 1846 1847 my $left = &parseBlock($b1); 1848 my $right = &parseBlock($b2); 1849 1850 print "[parseBlock (operator)] $left || $right\n" if $Debug > 2; 1851 1852 print "$b2 -> $right\n" if $b2 =~ /X0/ and $Debug > 2; 1853 print "$b2 -> $right\n" if $b2 =~ /wrap/ and $Debug > 2; 1854 1855 return $left . " $c1 " . $right; 1856 } 1857 1858 ############################################################################### 1859 # 1860 # comma-separated variables 1861 # 1862 # (Pattern 9) , 1863 # 1864 ############################################################################### 1865 elsif( $line =~ /,/) 1866 { 1867 my $org = $line; 1868 1869 print "[parseBlock(Pattern 9)] $line\n" if $Debug > 1; 1870 1871 # escapes "," in (.. , ..) 1872 $line =~ s{ ($re_np) }{ (my $r = $1) =~ s|,|_COMMA_|g; $r }xeg; 1873 1874 # escapes "," in ".. , .." or '.. , ..' 1875 $line =~ s{ ( " .*? (?<!\\) " ) }{ (my $r = $1) =~ s|,|_COMMA_|g; $r }xeg; 1876 $line =~ s{ ( ' .*? (?<!\\) ' ) }{ (my $r = $1) =~ s|,|_COMMA_|g; $r }xeg; 1877 1878 my @args = split(',', $line); 1879 1880 print "[split] $org -> @args\n" if $Debug > 2; 1881 1882 for (@args) 1883 { 1884 s/_COMMA_/,/g; 1885 } 1886 1887 # If we end up with only one item, we probably got caught in a comma 1888 # within arguments to a function call. 1889 1890 if (scalar(@args) == 1) 1891 { 1892 print "[parseBlock (line) ] $line\n" if $Debug > 1; 1893 return &convertVal($line); 1894 } 1895 1896 for (@args) 1897 { 1898 next if /^\s* ([\"\']).*(??{$1}) \s* $/x; 1899 print "args -> $_\n" if $Debug > 2; 1900 $_ = &parseBlock($_); 1901 } 1902 1903 print "[parseBlock(args) ] @args\n" if $Debug > 2; 1904 1905 ################################################## 1906 # Java / C# 1907 ################################################## 1908 if ( ($Target eq 'java') || ($Target eq 'csharp') ) 1909 { 1910 if ( $CurLine !~ /[\"\'\(\)]/ ) 1911 { 1912 my $cname = $args[0]; 1913 $cname =~ s/^\s*//; 1914 $cname =~ s/\s*$//; 1915 $cname =~ s/^ \s* (.+) \s+ .+ \s* $/$1/x; 1916 1917 if ( defined( $SBaseClass{$cname} ) || defined( $MiscClass{$cname} ) ) 1918 { 1919 return join(', ', @args); 1920 } 1921 } 1922 } 1923 1924 return @args; 1925 } 1926 ############################################################################### 1927 # 1928 # Others 1929 # 1930 # (Pattern 10) , 1931 # 1932 ############################################################################### 1933 else 1934 { 1935 print "[parseBlock (pattern 10)] $line\n" if $Debug > 1; 1936 return &convertVal($line); 1937 } 1938} 1939 1940 1941 1942sub addAssertion1 1943{ 1944 my ($line,$bool_flag) = @_; 1945 my $assertion; 1946 my $val = ""; 1947 1948 if ( $line =~ /UnitKind_( equals | isValidUnitKindString )/x) 1949 { 1950 $val = ($bool_flag) ? "1" : "0"; 1951 } 1952 else 1953 { 1954 $val = ($bool_flag) ? $IdTRUE{$Target} : $IdFALSE{$Target}; 1955 } 1956 1957 ################################################## 1958 # Ruby 1959 ################################################## 1960 if ($Target eq 'ruby') 1961 { 1962 $assertion = "assert_equal $val, $line"; 1963 } 1964 ################################################## 1965 # Python 1966 ################################################## 1967 elsif ($Target eq 'python') 1968 { 1969 $assertion = "self.assertEqual( $val, $line )"; 1970 } 1971 ################################################## 1972 # Java / C# 1973 ################################################## 1974 elsif ( ($Target eq 'java') || ($Target eq 'csharp') ) 1975 { 1976 $assertion = "assertEquals( $val, $line );"; 1977 } 1978 ###################################################################### 1979 1980#print "[addAssertion1] -> $assertion\n"; 1981 1982 print "[addAssertion1] -> $assertion\n" if $Debug; 1983 1984 return $assertion; 1985} 1986 1987 1988sub addAssertion2 1989{ 1990 my ($left,$right,$op) = @_; 1991 1992 my $assertion; 1993 1994 if ( $CurLine =~ /SyntaxChecker_ (isValid(XMLID|SBMLSId|UnitSId) | 1995 hasExpectedXHTMLSyntax )/x) 1996 { 1997 $left = $IdFALSE{$Target} if ($left eq '0'); 1998 $left = $IdTRUE{$Target} if ($left eq '1'); 1999 $right = $IdFALSE{$Target} if ($right eq '0'); 2000 $right = $IdTRUE{$Target} if ($right eq '1'); 2001 } 2002 2003 ################################################## 2004 # Ruby 2005 ################################################## 2006 if ($Target eq 'ruby') 2007 { 2008 if ( $CurLine =~ /fail_unless/ ) 2009 { 2010 $assertion = "assert( " . $left . " " . $op . " " . $right . " )"; 2011 } 2012 elsif ( $CurLine =~ /fail_if/ ) 2013 { 2014 $assertion = "assert( !( " . $left . " " . $op . " " . $right . ") )"; 2015 } 2016 } 2017 ################################################## 2018 # Python 2019 ################################################## 2020 elsif ($Target eq 'python') 2021 { 2022 if ( $CurLine =~ /fail_unless/ ) 2023 { 2024 #if ( $CurLine =~ / \s+ \! \s+ /x ) 2025 if ( $CurLine =~ / \( \s* \! \s* \w /x ) 2026 { 2027 $assertion = "self.assert_( (" . $left . " " . $op . " " . $right . ") == False )"; 2028 } 2029 else 2030 { 2031 $assertion = "self.assert_( " . $left . " " . $op . " " . $right . " )"; 2032 } 2033 } 2034 elsif ( $CurLine =~ /fail_if/ ) 2035 { 2036 $assertion = "self.assert_( (" . $left . " " . $op . " " . $right . ") == False )"; 2037 } 2038 } 2039 ################################################## 2040 # Java/C# 2041 ################################################## 2042 elsif ( ( $Target eq 'java' ) || ( $Target eq 'csharp' ) ) 2043 { 2044 my $equation = $left . " $op " . $right; 2045 2046#print "[In addAssertion2] -> $equation\n"; 2047 2048 if ( $Target eq 'java' ) 2049 { 2050 unless ( $right =~ /^ (?: 2051 [-+]?(\d+|\d*\.\d*)([eE][+-]?\d+)? 2052 | 2053 libsbml\..+ 2054 | 2055 true 2056 | 2057 false 2058 | 2059 null 2060 | 2061 '.*' 2062 | 2063 ".*" 2064 | 2065 [A-Z_]+ 2066 ) $/x 2067 ) 2068 { 2069 # sbml/TestCopyAndClone.cpp 2070 unless ( ($left =~ /getParentSBMLObject/ && $right =~ /getParentSBMLObject/) 2071 || 2072 ($left =~ /get ( InitialAmount 2073 |InitialConcentration 2074 |ExponentAsDouble 2075 |Multiplier 2076 |Scale 2077 |Size 2078 |Stoichiometry 2079 ) 2080 /x) 2081 || 2082 ($CurLine =~ / getCharacter /x ) 2083 ) 2084 { 2085 print "[turning into .equals] $left, $right\n" if $Debug > 2; 2086 $equation = $left . ".equals($right)"; 2087 $equation = "!" . $equation if ( $op =~ "!=" ); 2088 } 2089 } 2090 } 2091 2092 if ( $CurLine =~ /fail_unless/ ) 2093 { 2094 if ( $CurLine =~ / \( \s* \! \s* \w /x ) 2095 { 2096 $assertion = "assertTrue( ! (". $equation . ") );"; 2097 } 2098 else 2099 { 2100 $assertion = "assertTrue( ". $equation . " );"; 2101 } 2102 } 2103 elsif ( $CurLine =~ /fail_if/ ) 2104 { 2105 $assertion = "assertTrue( ! (". $equation . ") );"; 2106 } 2107 } 2108 ###################################################################### 2109 2110 print "[In addAssertion2] -> $assertion\n" if $Debug; 2111#print "[In addAssertion2] -> $assertion\n"; 2112 2113 return $assertion; 2114} 2115 2116sub convertMacroDefine 2117{ 2118 my ($args) = @_; 2119 my $mname; 2120 my $marg; 2121 my $mdef; 2122 2123 if ( $args =~ /^ \s* (\w+) ( \( \w+ \) )? \s* (.*)/x ) 2124 { 2125 $mname = $1 . $2; 2126 $marg = $2; 2127 $mdef = $3; 2128 } 2129 2130 $mname = $1 if ( $mname =~ /test_(.+)/ ); 2131 2132#print "[convertMacro] $mname || $marg || $mdef \n"; 2133 2134 ################################################## 2135 # Ruby / Python 2136 ################################################## 2137 if ( ( $Target eq 'ruby' ) || ( $Target eq 'python' ) ) 2138 { 2139 push (@{$MacroDef{$mname}}, "{"); 2140 2141 if ( $mdef =~ /^ \s* " ( (?:[^"]|\\")*? ) (?<!\\) " \s* $/x ) 2142 { 2143#print "[convertMacro(string)] $2 \n"; 2144 push (@{$MacroDef{$mname}}, "return \"$1\""); 2145 } 2146 elsif ( $mdef =~ /^ \s* ' ( (?:[^"]|\\")*? ) (?<!\\) ' \s* $/x ) 2147 { 2148 push (@{$MacroDef{$mname}}, "return \"$1\""); 2149 } 2150 elsif ( $mdef =~ /^ \s* ($re_np) \s* $/x ) 2151 { 2152 push (@{$MacroDef{$mname}}, "return $1"); 2153 } 2154 else 2155 { 2156 my @mdef_args = split('\s+',$mdef); 2157 my $flag = 0; 2158 2159#print "[convertMacro(function)] @mdef_args \n"; 2160 2161 for my $i (@mdef_args) 2162 { 2163 my $str = ($flag) ? "r += " : "r = "; 2164 $flag = 1 unless $flag; 2165 if ( defined ( $MacroDef{$i} ) ) 2166 { 2167 $str .= "${i}()"; 2168 } 2169 else 2170 { 2171 $str .= "${i}"; 2172 } 2173 2174#print "[convertMacro(function)] $str \n"; 2175 2176 push (@{$MacroDef{$mname}}, $str); 2177 } 2178 push (@{$MacroDef{$mname}}, "return r"); 2179 } 2180 2181 push (@{$MacroDef{$mname}}, "}"); 2182 } 2183 ################################################## 2184 # Java / C# 2185 ################################################## 2186 elsif ( ($Target eq 'java') || ($Target eq 'csharp') ) 2187 { 2188# $mname = $mname; 2189 # 2190 # Currently, by default, type of arugment in macro is 2191 # "String(Java) or string(C#)" 2192 # 2193 if ($mname =~ /isnan/) 2194 { 2195 $mname =~ s/ \( (\w+) \) /(double $1)/x; 2196 } 2197 elsif ($Target eq 'csharp') 2198 { 2199 $mname =~ s/ \( (\w+) \) /(string $1)/x; 2200 } 2201 else 2202 { 2203 $mname =~ s/ \( (\w+) \) /($IdSTRING{$Target} $1)/x; 2204 } 2205 2206 # matches "..." 2207 if ( $mdef =~ /^ \s* " ( (?:[^"]|\\")*? ) (?<!\\) " \s* $/x ) 2208 { 2209#print "[convertMacro(string)] $2 \n"; 2210 push (@{$MacroDef{$mname}}, "{"); 2211 push (@{$MacroDef{$mname}}, "return \"$1\";"); 2212 } 2213 # matches '...' 2214 elsif ( $mdef =~ /^ \s* ' ( (?:[^"]|\\")*? ) (?<!\\) ' \s* $/x ) 2215 { 2216 push (@{$MacroDef{$mname}}, "{"); 2217 push (@{$MacroDef{$mname}}, "return \"$1\";"); 2218 } 2219 # matches (...) 2220 elsif ( $mdef =~ /^ \s* ($re_np) \s* $/x ) 2221 { 2222 push (@{$MacroDef{$mname}}, "{"); 2223 push (@{$MacroDef{$mname}}, "return $1;"); 2224 } 2225 else 2226 { 2227 my @mdef_args = split('\s+',$mdef); 2228 my $flag = 0; 2229 2230#print "[convertMacro(function)] @mdef_args \n"; 2231 2232 push (@{$MacroDef{$mname}}, "{"); 2233 for my $i (@mdef_args) 2234 { 2235 my $str; 2236 if ($flag) 2237 { 2238 $str = "r += "; 2239 } 2240 else 2241 { 2242 # 2243 # currently, type of arugment in macro is fixed to "String" 2244 # 2245 $str = "$IdSTRING{$Target} r = "; 2246 $flag = 1; 2247 } 2248 2249 if ( defined ( $MacroDef{$i} ) ) 2250 { 2251 $str .= "${i}()"; 2252 } 2253 else 2254 { 2255 $str .= "${i}"; 2256 } 2257 2258#print "[convertMacro(function)] $str \n"; 2259 2260 push (@{$MacroDef{$mname}}, $str . ";"); 2261 } 2262 push (@{$MacroDef{$mname}}, "return r;"); 2263 } 2264 2265 push (@{$MacroDef{$mname}}, "}"); 2266 } 2267 2268 ###################################################################### 2269} 2270 2271sub convertCPPFuncCall 2272{ 2273 my($fcall) = @_; 2274 2275#print "[convertCPPFuncCall] $fcall\n"; 2276 2277# if ( $Target eq 'ruby' || $Target eq 'python' ) 2278# { 2279# if ( $fcall =~ /XMLNode.convertStringToXMLNode/ ) 2280# { 2281# $fcall = $Prefix{$Target} . $fcall; 2282# } 2283# } 2284 2285 ################################################## 2286 # Ruby 2287 ################################################## 2288 if ( $Target eq 'ruby' ) 2289 { 2290 $fcall =~ s/ -> /./gx; 2291 $fcall =~ s/^(\w+)\. / if ( defined( $GlobalVariable{$1} ) ) { "@@" . lc($1) . "." } else {lc($1). "."} /xe; 2292# $fcall =~ s/^([A-Z]{1,3})\. / "@@" . lc($1) . "."/xe; 2293 } 2294 ################################################## 2295 # Python 2296 ################################################## 2297 elsif ( $Target eq 'python' ) 2298 { 2299 $fcall =~ s/ -> /./gx; 2300# $fcall =~ s/^([A-Z]{1,3})\. / "@@" . lc($1) . "."/xe; 2301 } 2302 ################################################## 2303 # Java / C# 2304 ################################################## 2305 elsif ( ($Target eq 'java') || ($Target eq 'csharp') ) 2306 { 2307 $fcall =~ s/ -> /./gx; 2308 if ( $Target eq 'java' ) 2309 { 2310 $fcall =~ s/clone \s* \(/cloneObject\(/gx; 2311 } 2312# $fcall =~ s/^([A-Z]{1,3})\. / "@@" . lc($1) . "."/xe; 2313 } 2314 2315 ###################################################################### 2316 2317 return $fcall; 2318} 2319 2320sub convertCPPNew 2321{ 2322 my($cname,@arg) = @_; 2323 my $fcall = ""; 2324 2325 # 2326 # ignored classes 2327 # 2328 if ( defined( $IgnoredClass{$cname} ) ) 2329 { 2330 print "(IGNORED) [convertCPPNew] cname $cname arg @arg \n" if $Debug > 2; 2331 return $fcall; 2332 } 2333 2334 if ( ($cname eq "Rule") and ($CurLine !~ / (.*) = (.*) /x ) ) 2335 { 2336 print "(IGNORED) [convertCPPNew] cname $cname arg @arg \n" if $Debug > 2; 2337 return $fcall; 2338 } 2339 2340#print "[convertCPPNew] cname $cname arg @arg \n"; 2341 2342 ################################################## 2343 # Ruby 2344 ################################################## 2345 if ( $Target eq 'ruby' ) 2346 { 2347 my $args = join(',', @arg); 2348 $fcall = $cname . ".new($args)"; 2349 if ( defined( $SBaseClass{$cname} ) || defined( $MiscClass{$cname} ) ) 2350 { 2351 $fcall = $Prefix{'ruby'} . $fcall; 2352 } 2353 elsif ( $cname =~ 'ostringstream' ) 2354 { 2355 $fcall =~ s/ostringstream/Ostringstream/; 2356 $fcall = $Prefix{'ruby'} . $fcall; 2357 } 2358 2359 } 2360 ################################################## 2361 # Python 2362 ################################################## 2363 elsif ( $Target eq 'python' ) 2364 { 2365 my $args = join(',', @arg); 2366 $fcall = $cname . "($args)"; 2367 if ( defined( $SBaseClass{$cname} ) || defined( $MiscClass{$cname} ) ) 2368 { 2369 $fcall = $Prefix{'python'} . $fcall; 2370 } 2371 elsif ( $cname =~ 'ostringstream' ) 2372 { 2373 $fcall = $Prefix{'python'} . $fcall; 2374 } 2375#print "[convertCPPNew] cname $cname arg @arg fcall $fcall \n"; 2376 } 2377 ################################################## 2378 # Java / C# 2379 ################################################## 2380 elsif ( ($Target eq 'java') || ($Target eq 'csharp') ) 2381 { 2382 my $args = join(',', @arg); 2383 $fcall = $cname . "($args)"; 2384 $fcall =~ s/\(std\:nothrow\)//g; 2385 if ( defined( $SBaseClass{$cname} ) || defined( $MiscClass{$cname} ) ) 2386 { 2387 $fcall = "new " . $fcall; 2388 } 2389 elsif ( $cname =~ 'ostringstream' ) 2390 { 2391 $fcall =~ s/ostringstream/OStringStream/; 2392# $fcall = "new " . $Prefix{'java'} . $fcall; 2393 $fcall = "new " . $fcall; 2394 } 2395 } 2396 ###################################################################### 2397 2398#print "[convertCPPNew] $fcall\n"; 2399 2400 return $fcall; 2401} 2402 2403sub convertSBaseCFuncCall 2404{ 2405 my($cname,$fname,@arg) = @_; 2406 my $fcall = ""; 2407 2408 print "[convertSBaseCFuncCall] cname = $cname\n" if $Debug > 2; 2409 print "[convertSBaseCFuncCall] fname = $fname\n" if $Debug > 2; 2410 print "[convertSBaseCFuncCall] arg = @arg\n" if $Debug > 2; 2411 2412 foreach ( keys %IgnoredFunc ) 2413 { 2414 if ( $fname =~ /$_/ ) 2415 { 2416 print "(IGNORED) [convertSBaseCFuncCall] ${cname}_${fname} (@arg) \n" if $Debug > 2; 2417 return; 2418 } 2419 } 2420 2421 if ( $fname !~ /get.*IndexByPrefix/ ) 2422 { 2423 $fname =~ s/By[A-Z].+$//; 2424 } 2425 $fname =~ s/( (?:set|append) (?:Annotation|Notes) ) String /$1/x; 2426 $fname =~ s/^ set( Integer$ | Real$ | RealWithExponent | Rational)/setValue/x; 2427 $fname =~ s/( addAttr ) With (?:NS|Triple)/$1/x; 2428 $fname =~ s/( add ) With (?:Triple)/$1/x; 2429 $fname =~ s/( setSBOTerm ) ID /$1/x; 2430 $fname =~ s/( setExponent ) AsDouble /$1/x; 2431 $fname =~ s/( setSpatialDimensions ) AsDouble /$1/x; 2432 2433 if ( $fname =~ /setLevelAndVersion/ ) 2434 { 2435 if ( $fname =~ /NonStrict/ ) 2436 { 2437 push (@arg, $IdFALSE{$Target} ); 2438 } 2439 else 2440 { 2441 push (@arg, $IdTRUE{$Target} ); 2442 } 2443 $fname =~ s/(?:Non)?Strict//; 2444 } 2445 2446 # 2447 # Removes the last argument because the constructer of Reaction 2448 # class accepts only four arguments. 2449 # 2450 if ( ( $cname eq 'Reaction' ) and ( $fname eq 'createWithKineticLaw' ) ) 2451 { 2452 if ( scalar(@arg) == 5 ) 2453 { 2454 pop(@arg); 2455 2456 if ( $arg[3] != 0 ) 2457 { 2458 $arg[3] = $IdTRUE{$Target}; 2459 } 2460 else 2461 { 2462 $arg[3] = $IdFALSE{$Target}; 2463 } 2464 2465 } 2466 } 2467 2468 # C functions corresponding to static C++ class functions 2469 if ( $cname eq 'XMLNode' ) 2470 { 2471 if ( $fname eq 'convertStringToXMLNode' ) 2472 { 2473 if ( ($Target eq 'java') || ($Target eq 'csharp') ) 2474 { 2475 $fcall = $cname . "." . $fname; 2476 } 2477 else 2478 { 2479 $fcall = $Prefix{$Target} . $cname . "." . $fname; 2480 } 2481 $fcall .= '(' . join(",",@arg) . ')'; 2482 return $fcall; 2483 } 2484 elsif ( $fname =~ /^create/ ) 2485 { 2486 $fcall = "new " . $cname . '(' . join(",",@arg) . ')'; 2487 return &parseBlock($fcall); 2488 } 2489 } 2490 2491 if ( $cname eq 'UnitDefinition' ) 2492 { 2493 if ( $fname eq 'printUnits' ) 2494 { 2495 if ( ($Target eq 'java') || ($Target eq 'csharp') ) 2496 { 2497 $fcall = $cname . "." . $fname; 2498 } 2499 else 2500 { 2501 $fcall = $Prefix{$Target} . $cname . "." . $fname; 2502 } 2503 2504 if ( scalar(@arg) == 2) 2505 { 2506 if ( $arg[1] != 0 ) 2507 { 2508 $arg[1] = $IdTRUE{$Target}; 2509 } 2510 else 2511 { 2512 $arg[1] = $IdFALSE{$Target}; 2513 } 2514 } 2515 2516 $fcall .= '(' . join(",",@arg) . ')'; 2517 return $fcall; 2518 } 2519 } 2520 2521 if ( $cname eq 'ListOf' ) 2522 { 2523 if ($fname =~ /^clear/) 2524 { 2525 $arg[1] = $IdFALSE{$Target} if ( $arg[1] eq '0' ); 2526 $arg[1] = $IdTRUE{$Target} if ( $arg[1] eq '1' ); 2527 } 2528 } 2529 2530 if ( $cname eq 'RDFAnnotationParser' || 2531 $cname eq 'SyntaxChecker' ) 2532 { 2533 if ( ($Target eq 'java') || ($Target eq 'csharp') ) 2534 { 2535 $fcall = $cname . "." . $fname; 2536 } 2537 else 2538 { 2539 $fcall = $Prefix{$Target} . $cname . "." . $fname; 2540 } 2541 2542 $fcall .= '(' . join(",",@arg) . ')'; 2543 return $fcall; 2544 } 2545 2546# print "[In convertSBaseCFuncCall] -> $cname $fname @arg\n"; 2547#print "[convertSBaseCFuncCall] $cname || $fname || @arg\n"; 2548 2549 if ($fname =~ /^create.*WithLevelVersionAndNamespaces/) 2550 { 2551 $arg[2] = $IdNULL{$Target} if ( $arg[2] eq "0" ) ; 2552 } 2553 2554 $fcall = $fname; 2555 if ($fname =~ /free$/) 2556 { 2557 my $args = join(",", @arg); 2558 2559 if ($Target eq 'python') 2560 { 2561 # Crude way of simulating deletion in Python. 2562 # 2563 return "_dummyList = [ $args ]; _dummyList[:] = []; del _dummyList"; 2564 } 2565 else 2566 { 2567 # FIXME need to find appropriate solutions for other languages. 2568 2569 return "" if $args =~ /$IdNULL{$Target}/; 2570 return "$args = $IdNULL{$Target}"; 2571 } 2572 } 2573 elsif ( $cname eq 'XMLInputStream' ) 2574 { 2575 if ($fname =~ /^create/) 2576 { 2577 $arg[1] = $IdFALSE{$Target} if ( $arg[1] eq '0' ); 2578 $arg[1] = $IdTRUE{$Target} if ( $arg[1] eq '1' ); 2579 2580 return &getCreateObjString($cname, join(",", @arg)); 2581 } 2582 } 2583 elsif($fname =~ /^create$/) 2584 { 2585 return &getCreateObjString($cname, join(",", @arg)); 2586# return &getCreateObjString($cname,""); 2587 } 2588 elsif($fname =~ /^create(With|From)/) 2589 { 2590#print "$cname @arg\n"; 2591 return &getCreateObjString($cname, join(",",@arg)); 2592 } 2593 elsif ( $cname eq 'XMLOutputStream' ) 2594 { 2595 if ($fname =~ /^create/) 2596 { 2597 $arg[1] = $IdFALSE{$Target} if ( $arg[1] eq '0' ); 2598 $arg[1] = $IdTRUE{$Target} if ( $arg[1] eq '1' ); 2599 2600 $arg[2] = $IdFALSE{$Target} if ( $arg[2] eq '0' ); 2601 $arg[2] = $IdTRUE{$Target} if ( $arg[2] eq '1' ); 2602 } 2603 2604 if ($fname =~ /^createAsStdout/) 2605 { 2606 unshift ( @arg, $IdCOUT{$Target} ); 2607 2608 return &getCreateObjString($cname, join(",",@arg)); 2609 } 2610 elsif ($fname =~ /^createAsString/) 2611 { 2612 push (@{$FuncDef{$CurFunc}}, $IdOSS{$Target}); 2613 2614 unshift ( @arg, "oss" ); 2615 2616 return &getCreateObjString($cname, join(",",@arg)); 2617 } 2618 elsif ($fname =~ /^createFile/) 2619 { 2620 $arg[0] = &getCreateFileString($arg[0]); 2621 return &getCreateObjString($cname, join(",",@arg)); 2622 } 2623 elsif ($fname =~ /^getString/) 2624 { 2625 return "oss.str()"; 2626 } 2627 } 2628 elsif ( $cname eq 'Rule') 2629 { 2630 if ($fname =~ /^create(Algebraic|Assignment|Rate)/) 2631 { 2632 my $dcname = $1 . "Rule"; 2633 2634 return &getCreateObjString($dcname, join(",",@arg)); 2635 } 2636 } 2637 elsif ( $cname eq 'SpeciesReference') 2638 { 2639 if ($fname =~ /^createModifier/) 2640 { 2641 my $dcname = "ModifierSpeciesReference"; 2642 2643 return &getCreateObjString($dcname, join(",",@arg)); 2644 } 2645 } 2646 elsif ( $cname eq 'UnitKind') 2647 { 2648 if ($fname =~ /^forName/) 2649 { 2650 $fcall = $Prefix{$Target} . "UnitKind_forName"; 2651 $fcall .= '(' . join(",",@arg) . ')'; 2652 return $fcall; 2653 } 2654 elsif ($fname =~ /^equals/) 2655 { 2656 $fcall = $Prefix{$Target} . "UnitKind_equals"; 2657 $arg[0] = '""' if $arg[0] eq $IdNULL{$Target}; 2658 $fcall .= '(' . join(",",@arg) . ')'; 2659 return $fcall; 2660 } 2661 elsif ($fname =~ /^isValidUnitKindString/) 2662 { 2663 $fcall = $Prefix{$Target} . "UnitKind_isValidUnitKindString"; 2664 $arg[0] = '""' if $arg[0] eq $IdNULL{$Target}; 2665 $fcall .= '(' . join(",",@arg) . ')'; 2666 return $fcall; 2667 } 2668 elsif ($fname =~ /^toString/) 2669 { 2670 $fcall = $Prefix{$Target} . "UnitKind_toString"; 2671 $arg[0] = '""' if $arg[0] eq $IdNULL{$Target}; 2672 $fcall .= '(' . join(",",@arg) . ')'; 2673 return $fcall; 2674 } 2675 } 2676 elsif ( $cname eq 'Unit') 2677 { 2678 if ($fname =~ /^ (isBuiltIn|removeScale) /x ) 2679 { 2680 ################################################## 2681 # Java / C# 2682 ################################################## 2683 if ( ($Target eq 'java') || ($Target eq 'csharp') ) 2684 { 2685 $fcall = "Unit.$1"; 2686 } 2687 ################################################## 2688 # Python/Ruby 2689 ################################################## 2690 else 2691 { 2692 $fcall = $Prefix{$Target} . "Unit.$1"; 2693 } 2694 2695 $arg[0] = '""' if $arg[0] eq $IdNULL{$Target}; 2696 $fcall .= '(' . join(",",@arg) . ')'; 2697 return $fcall; 2698 } 2699 } 2700 elsif ( $cname eq 'SBML') 2701 { 2702 if ($fname =~ /^parseFormula/) 2703 { 2704 $fcall = $Prefix{$Target} . "parseFormula"; 2705 $fcall .= '(' . join(",",@arg) . ')'; 2706 return $fcall; 2707 } 2708 elsif ($fname =~ /^formulaToString/) 2709 { 2710 $fcall = $Prefix{$Target}. "formulaToString"; 2711 $fcall .= '(' . join(",",@arg) . ')'; 2712 return $fcall; 2713 } 2714 } 2715 2716 if (defined($arg[0])) 2717 { 2718 if ( $arg[0] =~ /^\((.*)\)/x ) 2719 { 2720 my $actual = $1; 2721 if ( $Target eq 'python' ) 2722 { 2723 $arg[0] = "(self." . $actual . ")" if ( defined( $GlobalVariable{$actual} ) ); 2724 } 2725 elsif ( $Target eq 'ruby' ) 2726 { 2727 $arg[0] = "@@" . lc($actual) . "" if ( defined( $GlobalVariable{$actual} ) ); 2728 } 2729 } 2730 2731 $fcall = $arg[0] . "." . $fname; 2732 2733 if (defined($arg[1])) 2734 { 2735 if ( $cname ne 'ASTNode' && 2736 $fname =~ /^\s*set( Id 2737 |MetaId 2738 |Name 2739 |Variable 2740 |TimeUnits 2741 |Outside 2742 |Units 2743 |Formula 2744 |SpatialSizeUnits 2745 |SubstanceUnits 2746 |Compartment 2747 |CompartmentType 2748 |Species 2749 |SpeciesType 2750 |Symbol 2751 |ProgramName 2752 |ProgramVersion 2753 |DateAsString 2754 ) \s* $ 2755 /x 2756 ) 2757 { 2758 $arg[1] = '""' if $arg[1] eq $IdNULL{$Target}; 2759 } 2760 elsif ( $fname =~ /^ \s* set( BoundaryCondition 2761 |Constant 2762 |Fast 2763 |Reversible 2764 |BoundaryCondition 2765 |ConstanHasOnlySubstanceUnits 2766 |UseValuesFromTriggerTime 2767 |HasOnlySubstanceUnits 2768 ) 2769 /x 2770 ) 2771 { 2772 $arg[1] = $IdFALSE{$Target} if $arg[1] == '0'; 2773 $arg[1] = $IdTRUE{$Target} if $arg[1] != '0'; 2774 } 2775 if ($fname =~ /^ \s* set(Annotation|Notes) /x ) 2776 { 2777 $arg[1] = "(XMLNode)null" if ( $arg[1] =~ /null/ ); 2778 } 2779 elsif ($fname =~ /^(writeAttribute)/) 2780 { 2781 my $lfname = $1; 2782 2783 ################################################## 2784 # Ruby & Python 2785 ################################################## 2786 if ($Target eq 'ruby' || $Target eq 'python' || $Target eq 'csharp' ) 2787 { 2788 if ( $arg[1] =~ /bool/) 2789 { 2790 $arg[2] = $IdFALSE{$Target} if $arg[2] == '0'; 2791 $arg[2] = $IdTRUE{$Target} if $arg[2] != '0'; 2792 $lfname .= "Bool" if ( $Target ne 'csharp' ); 2793 } 2794 } 2795 elsif ( $Target eq 'java' ) 2796 { 2797 if ( $arg[1] =~ /bool/) 2798 { 2799 $arg[2] = $IdFALSE{$Target} if $arg[2] == '0'; 2800 $arg[2] = $IdTRUE{$Target} if $arg[2] != '0'; 2801 } 2802 } 2803 2804 $fcall = $arg[0] . "." . $lfname; 2805 } 2806 elsif ($fname =~ /^ (add)With(?: Namespace | Triple ) /x ) 2807 { 2808 my $lfname = $1; 2809 2810 $fcall = $arg[0] . "." . $lfname; 2811 } 2812 elsif ($fname =~ /^(getModifiedDate)FromList/) 2813 { 2814 my $lfname = $1; 2815 2816 $fcall = $arg[0] . "." . $lfname; 2817 } 2818 elsif ($fname =~ /^(hasAttribute)/) 2819 { 2820 $fcall = $arg[0] . "." . $1; 2821 } 2822 elsif ($fname =~ /^(hasAttr)With/) 2823 { 2824 $fcall = $arg[0] . "." . $1; 2825 } 2826 2827 shift(@arg); 2828 $fcall .= '(' . join(",",@arg) . ')'; 2829 } 2830 else 2831 { 2832 $fcall .= '()'; 2833 } 2834 } 2835 else 2836 { 2837 ################################################## 2838 # Java / C# 2839 ################################################## 2840 if ( ($Target eq 'java') || ($Target eq 'csharp') ) 2841 { 2842 $fcall = $cname . "." . $fname. "()"; 2843 } 2844 ################################################## 2845 # Python/Ruby 2846 ################################################## 2847 else 2848 { 2849 $fcall = $Prefix{$Target} . $cname . "." . $fname . "()"; 2850 } 2851 2852 } 2853 2854 return $fcall; 2855} 2856 2857 2858sub convertCFuncCall 2859{ 2860 my($fname,@arg) = @_; 2861 my $fcall = ""; 2862 2863#print "[convertCFuncCall] $fname || @arg\n"; 2864 2865 $fcall = $fname; 2866 if($fname =~ /^ (!?) \s* strcmp/x ) 2867 { 2868 if ( $1 ne '!' ) 2869 { 2870 ################################################## 2871 # Java 2872 ################################################## 2873 if($Target eq 'java') 2874 { 2875 $fcall = "!$arg[0].equals($arg[1])"; 2876 } 2877 else 2878 { 2879 $fcall = "( " . $arg[1] . " != " . $arg[0] . " )"; 2880 } 2881 } 2882 else 2883 { 2884 ################################################## 2885 # Java 2886 ################################################## 2887 if($Target eq 'java') 2888 { 2889 $fcall = "$arg[0].equals($arg[1])"; 2890 } 2891 else 2892 { 2893 $fcall = "( " . $arg[1] . " == " . $arg[0] . " )"; 2894 } 2895 } 2896 } 2897 elsif($fname =~ /^ \s* (read(?:SBML|MathML)(?:FromString)?)\s*$/x ) 2898 { 2899 $fcall = "$Prefix{$Target}${1}(" . $arg[0] . ")"; 2900 } 2901 elsif($fname =~ /^ \s* (parseLayoutAnnotation?)\s*$/x ) 2902 { 2903 my $args = join(',', @arg); 2904 $fcall = "$Prefix{$Target}${1}(" . $args . ")"; 2905 } 2906 elsif($fname =~ /^ \s* (write(?:SBML|MathML)(?:ToString)?)\s*$/x ) 2907 { 2908 $fcall = "$Prefix{$Target}${1}(" . $arg[0] . ")"; 2909 } 2910 elsif($fname =~ /^ \s* safe_strcat/x ) 2911 { 2912 if ( $arg[0] =~ /TestDataDirectory/ ) 2913 { 2914 $arg[1] =~ s/"//g; 2915 $arg[1] =~ s/^\s*//; 2916 $arg[1] =~ s/\s*$//; 2917 $arg[1] = '"' . $TestDataDirectory . $arg[1] . '"' if ( $arg[0] =~ /TestDataDirectory/ ); 2918 } 2919 $fcall = $arg[1]; 2920 ######### 2921 } 2922 elsif( $fname =~ /^ \s* fail\b/x ) 2923 { 2924 # 2925 # fail() is IGNORED for now. 2926 # return 'flunk ' . $args; 2927 # $fcall = '#flunk ' . $arg[0]; 2928 } 2929 elsif( $fname =~ /^ \s* wrap(SBML|XML|MathML) /x ) 2930 { 2931 my $args = join(',', @arg); 2932 $fcall = "$fname". "(" . $args . ")"; 2933 } 2934 elsif( $fname =~ /^ \s* equals /x ) 2935 { 2936 my $args = join(',', @arg); 2937 $fcall = $fname . "(" . $args . ")"; 2938 ################################################## 2939 # Python 2940 ################################################## 2941 $fcall = "self." . $fcall if($Target eq 'python'); 2942 } 2943 elsif ( $fname =~ /^ \s* (?: abs ) /x ) 2944 { 2945 if ( $Target eq 'java' ) 2946 { 2947 my $args = join(',', @arg); 2948 $fcall = "java.lang.Math.abs(" . $args . ")"; 2949 } 2950 elsif ( $Target eq 'ruby' ) 2951 { 2952 my $args = join(',', @arg); 2953 $fcall = "(" . $args . ").abs"; 2954 } 2955 elsif ( $Target eq 'csharp' ) 2956 { 2957 my $args = join(',', @arg); 2958 $fcall = "Math.Abs(" . $args . ")"; 2959 } 2960 elsif ( $Target eq 'python' ) 2961 { 2962 my $args = join(',', @arg); 2963 $fcall = "abs(" . $args . ")"; 2964 } 2965 } 2966 elsif ( $fname =~ /^ \s* (?: test_isnan | util_isInf | isnan ) /x ) 2967 { 2968 $fname = "isnan" if $fname =~ /isnan/; 2969 my $args = join(',', @arg); 2970 $fcall = "$fname". "(" . $args . ")"; 2971 } 2972 elsif ($fname =~ /^ \s* free \s* $/x) 2973 { 2974 my $args = join(",", @arg); 2975 if ( $args =~ /$IdNULL{$Target}/ ) 2976 { 2977 $fcall = ""; 2978 } 2979 else 2980 { 2981 $fcall = "$args = $IdNULL{$Target}"; 2982 } 2983 } 2984 else 2985 { 2986 # ignored 2987 } 2988 2989 return $fcall; 2990} 2991 2992 2993 2994sub convertVal 2995{ 2996 my ($val) = @_; 2997 2998 print "[convertVal] $val\n" if $Debug > 1; 2999 3000 my $is_tail = 0; 3001 my $cast = ""; 3002 3003 $val =~ s/^\s+//; 3004 $val =~ s/\s+$//; 3005 $is_tail = 1 if ($val =~ s/;+$//) ; 3006 3007 # string "..." 3008 return $val if ($val =~ /^ " (?:[^"]|\\")*? (?<!\\) " $/x); 3009 # string '...' 3010 return $val if ($val =~ /^ ' (?:[^']|\\')*? (?<!\\) ' $/x); 3011 3012 # cast 3013 if ($val =~ /^ ( \( \w+ \s* \* \) ) \s* \(* (\w+) \)* $/x) 3014 { 3015 $cast = $1; 3016 $val = $2; 3017 3018 print "[convertVal (typecast)] $cast || $val\n" if $Debug > 1; 3019 3020 ################################################## 3021 # Java 3022 ################################################## 3023 if ( $Target eq 'java' ) 3024 { 3025 if ( $CurLine =~ /^ \s* \w*? \s* SpeciesReference .* (?: _createModifier | MSR )/x ) 3026 { 3027 $cast =~ s/^\s* (\w*?) \s* SpeciesReference_t/$1 SimpleSpeciesReference/x; 3028 } 3029 } 3030 ################################################## 3031 } 3032 3033 # dereference/reference 3034 $val = $1 if ($val =~ /^ \( \s* [\*&] \s* (\w+) \) /x); 3035 $val = $1 if ($val =~ /^ \s* [\*&] \s* \( (\w+) \) /x); 3036 $val = $1 if ($val =~ /^ \s* [\*&] \s* (\w+) /x); 3037 3038 # type 3039 if ($val =~ /^ (?: ( const | unsigned ) \s* )? (\w+? \s* \*?) \s* (\b \w+) $/x) 3040 { 3041 print "[convertVal (val)] $val (1) $1 (2) $2 (3) $3\n" if $Debug > 2; 3042 3043 my $type; 3044 my $modifier = $1; 3045 my $maintype = $2; 3046 my $ivartmp = $3; 3047 3048 if ( $Target eq 'java' and $modifier =~ /unsigned/x and $maintype =~ /int/x ) 3049 { 3050 $type = "long"; 3051 } 3052 elsif ( $modifier =~ /const/x ) 3053 { 3054 $type = "$maintype"; 3055 } 3056 else 3057 { 3058 $type = "$modifier $maintype"; 3059 } 3060 3061 my $ivar = &parseBlock($ivartmp); 3062 3063 $type =~ s/\s*//g; 3064 $ivar =~ s/\s*//g; 3065 3066 print "[convertVal (type)/(val)] type $type val $ivar \n" if $Debug > 2; 3067 3068 if ( defined ( $IgnoredClass{$type} ) ) 3069 { 3070 print "(IGNORED) [convertVal (class ivar) ] $type $ivar \n" if $Debug > 2; 3071 $LocalVariable{$CurFunc}{$ivar} = 0; 3072 return; 3073 } 3074 elsif ( defined ( $SBaseClass{$type} ) || defined ( $MiscClass{$type} ) ) 3075 { 3076 print "[convertVal (class $type) ] $type $ivar \n" if $Debug > 2; 3077 3078 $LocalVariable{$CurFunc}{$ivar} = 1; 3079 3080 # $type $ivar = $type(...); 3081 unless ( $is_tail ) 3082 { 3083 return "$type $ivar" if ( ( $Target eq 'java' ) || ( $Target eq 'csharp' )); 3084 return $ivar; 3085 } 3086 3087 # $type $ivar; 3088 my $r; 3089 3090 ################################################## 3091 # Java / C# 3092 ################################################## 3093 if ( ( $Target eq 'java' ) || ( $Target eq 'csharp' )) 3094 { 3095 $r = $type . " " . $ivar . " = ". &convertCPPNew($type); 3096 } 3097 ################################################## 3098 # Ruby/Python 3099 ################################################## 3100 else 3101 { 3102 $r = $ivar . " = ". &convertCPPNew($type); 3103 } 3104 print "[convertVal (r)] $r \n" if $Debug > 2; 3105 3106 return $r; 3107 } 3108 elsif ( $type =~ /delete/ ) 3109 { 3110 if ( ( $Target eq 'java' ) || ( $Target eq 'csharp' )) 3111 { 3112 unless ( $LocalVariable{$CurFunc}{$ivar} or $GlobalVariable{$ivar} ) 3113 { 3114 print "(IGNORED) delete $ivar \n" if $Debug > 2; 3115 return; 3116 } 3117 } 3118 3119 ################################################## 3120 # Ruby 3121 ################################################## 3122 if ($Target eq 'ruby') 3123 { 3124 return "$ivar = nil" 3125 } 3126 ################################################## 3127 # Python 3128 ################################################## 3129 elsif ($Target eq 'python') 3130 { 3131 return "$ivar = None" 3132 } 3133 ################################################## 3134 # Java / C# 3135 ################################################## 3136 elsif ( ( $Target eq 'java' ) || ( $Target eq 'csharp' )) 3137 { 3138 return "$ivar = null;" 3139 } 3140 } 3141 else 3142 { 3143 print "[convertVal (type mangling) ]\n" if $Debug > 2; 3144 3145 ################################################## 3146 # Java / C# 3147 ################################################## 3148 if ( ( $Target eq 'java' ) || ( $Target eq 'csharp' )) 3149 { 3150 $type =~ s/\* \s* $//x; 3151 if ( $CurLine =~ /^ \s* \w*? \s* SpeciesReference .* (?: _createModifier | MSR )/x ) 3152 { 3153 $type =~ s/^ \s* (\w*?) \s* SpeciesReference_t \s* $/$1 ModifierSpeciesReference/x; 3154 } 3155 elsif ( $CurLine =~ /^ \s* \w*? \s* SpeciesReference .* \s* ssr /x ) 3156 { 3157 $type =~ s/^ \s* (\w*?) \s* SpeciesReference_t \s* $/$1 SimpleSpeciesReference/x; 3158 } 3159 elsif ( $CurLine =~ /^ \s* \w*? \s* SpeciesReference .* \s* msr /x ) 3160 { 3161 $type =~ s/^ \s* (\w*?) \s* SpeciesReference_t \s* $/$1 ModifierSpeciesReference/x; 3162 } 3163 elsif ( $type =~ /^char$/ && $CurLine !~ /getCharacter(:!s)/x ) 3164 { 3165 $type =~ s/^char$/$IdSTRING{$Target}/x; 3166 } 3167 3168 $type =~ s/ _t \s* $//x; 3169 $type =~ s/^string$/$IdSTRING{$Target}/x; 3170 $type =~ s/^unsigned int$/long/x; 3171 3172 if ( $Target ne 'java' && $Target ne 'csharp' ) 3173 { 3174 $type =~ s/^int$/long/x; 3175 } 3176 3177 print "[convertVal (type var) decl ] $type $ivar \n" if $Debug > 2; 3178 3179 $LocalVariable{$CurFunc}{$ivar} = 1; 3180 3181 print "[convertVal (return)] $type $ivar \n" if $Debug > 2; 3182 3183 return "$type $ivar" 3184 } 3185 ################################################## 3186 3187 print "[convertVal (return)] $ivar \n" if $Debug > 2; 3188 3189 return $ivar; 3190 } 3191 } 3192 3193 print "[convertVal (var) ] $val \n" if $Debug > 2; 3194 3195 $val = $IdNULL{$Target} if ( $val =~ /^ \s* NULL \s* $/x ); 3196 # libSBML constants 3197 $val = $Prefix{$Target} . $val if ( $val =~ /^SBML_[A-Z]+/); 3198 $val = $Prefix{$Target} . $val if ( $val =~ /^SPECIES_[A-Z]+/); 3199 $val = $Prefix{$Target} . $val if ( $val =~ /^LIBSBML_[A-Z]+/); 3200 $val = $Prefix{$Target} . $val if ( $val =~ /^BIOLOGICAL_[A-Z]+/); 3201 $val = $Prefix{$Target} . $val if ( $val =~ /^BQB_[A-Z]+/); 3202 $val = $Prefix{$Target} . $val if ( $val =~ /^BQM_[A-Z]+/); 3203 $val = $Prefix{$Target} . $val if ( $val =~ /^MODEL_[A-Z]+/); 3204 $val = $Prefix{$Target} . $val if ( $val =~ /^AST_[A-Z]+/); 3205 $val = $Prefix{$Target} . $val if ( $val =~ /^RULE_TYPE_[A-Z]+/); 3206 $val = $Prefix{$Target} . $val if ( $val =~ /^UNIT_KIND_[A-Z]+/); 3207 $val = $Prefix{$Target} . $val if ( $val =~ /^XMLFile[A-Z]/); 3208 3209 $val = $Prefix{$Target} . $val if ( $val =~ /^DuplicateXMLAttribute/); 3210 $val = $Prefix{$Target} . $val if ( $val =~ /^EmptyListInReaction/); 3211 $val = $Prefix{$Target} . $val if ( $val =~ /^OverdeterminedSystem/); 3212 $val = $Prefix{$Target} . $val if ( $val =~ /^OffsetNoLongerValid/); 3213 $val = $Prefix{$Target} . $val if ( $val =~ /^NoSBOTermsInL1/); 3214 $val = $Prefix{$Target} . $val if ( $val =~ /^DisallowedMathMLEncodingUse/); 3215 $val = $Prefix{$Target} . $val if ( $val =~ /^UnknownError/); 3216 3217 $val = $constDBL_EPSILON{$Target} if ( $val =~ /^DBL_EPSILON$/); 3218 $val = $constSBML_INT_MAX{$Target} if ( $val =~ /SBML_INT_MAX/); 3219 $val = $IdTRUE{$Target} if ( $val =~ /^true$/); 3220 $val = $IdFALSE{$Target} if ( $val =~ /^false$/); 3221 3222 if ($Target eq 'ruby') 3223 { 3224 # ruby class static variable 3225 $val = "@@" . lc($val) if ( defined( $GlobalVariable{$val} ) ); 3226 # ruby local variable 3227 $val = lc($val) if ( $val =~ /^[A-Z][_a-z0-9]+$/); 3228 $val = lc($val) if ( $val =~ /^ ( N | EMAIL | ORG | NS | CVTerm[12] ) $/x); 3229 # floating point 3230 $val = '0' . $val if ( $val =~ /^\.[0-9]+$/ ); 3231 } 3232 elsif ($Target eq 'python') 3233 { 3234 $val = "self.${val}" if ( defined( $GlobalVariable{$val} ) ); 3235 } 3236 $val =~ s/-> \s* (\w)/.$1/xg; 3237 3238 ################################################## 3239 3240 return $val; 3241} 3242 3243 3244###################################################################### 3245# 3246# Output 3247# 3248###################################################################### 3249 3250# not used 3251sub getFuncHeader 3252{ 3253 my ($func_name, @args) = @_; 3254 my $func_header = ""; 3255 3256 ################################################## 3257 # Ruby 3258 ################################################## 3259 if($Target eq 'ruby') 3260 { 3261 $func_header .= "def $func_name"; 3262 if ( @args ) 3263 { 3264 $func_header .= "(" . join(',',@args) . ")"; 3265 } 3266 } 3267 ################################################## 3268 # Python 3269 ################################################## 3270 elsif($Target eq 'python') 3271 { 3272 $func_header .= "def $func_name"; 3273 if ( @args ) 3274 { 3275 $func_header .= "(" . join(',',@args) . ")"; 3276 } 3277 $func_header .= ":"; 3278 } 3279 ################################################## 3280 3281 return $func_header; 3282} 3283 3284# not used 3285sub getFuncFooter 3286{ 3287 my $func_footer = ""; 3288 3289 ################################################## 3290 # Ruby 3291 ################################################## 3292 if ($Target eq 'ruby') 3293 { 3294 $func_footer = "end"; 3295 } 3296 ################################################## 3297 3298 return $func_footer; 3299} 3300 3301sub printFuncDef 3302{ 3303 my ($func, $funcRef, $fh, $offset, $is_global) = @_; 3304 my $indent_offset = $offset; 3305 my $indent = 0; 3306 my $inBlock = 0; 3307 3308 return if $func =~ /^\s*$/; 3309 3310 ################################################## 3311 # Ruby 3312 ################################################## 3313 if ($Target eq 'ruby') 3314 { 3315 print $fh " " x ($indent+$indent_offset); 3316 print $fh "def $func\n"; 3317 3318 for(my $i=0; $i < @{$funcRef}; $i++ ) 3319 { 3320 my $l = ${$funcRef}[$i]; 3321 $l =~ s/^\s*//; 3322 3323 if ( $l eq "}" ) 3324 { 3325 $indent -= 2; 3326 if ($inBlock) 3327 { 3328 print $fh " " x ($indent+$indent_offset); 3329 print $fh "end" . "\n"; 3330 } 3331 next; 3332 } 3333 elsif ( $l eq "{" ) 3334 { 3335 $inBlock = 1; 3336 $indent += 2; 3337 next; 3338 } 3339 3340 print $fh " " x ($indent+$indent_offset); 3341 print $fh $l . "\n"; 3342 } 3343 3344 $indent = 0; 3345 print $fh "\n"; 3346 } 3347 ################################################## 3348 # Python 3349 ################################################## 3350 elsif ($Target eq 'python') 3351 { 3352 print $fh " " x ($indent+$indent_offset); 3353 3354 if ($is_global) 3355 { 3356 print $fh "def $func"; 3357 print $fh "()" unless $func =~ /$re_np/; 3358 print $fh ":\n"; 3359 } 3360 else 3361 { 3362 print $fh "def $func(self):\n"; 3363 } 3364 3365 for(my $i=0; $i < @{$funcRef}; $i++ ) 3366 { 3367 my $l = ${$funcRef}[$i]; 3368 $l =~ s/^\s*//; 3369 3370 if ( $l eq "}" ) 3371 { 3372 if ($inBlock) 3373 { 3374 print $fh " " x ($indent+$indent_offset); 3375 print $fh "pass"; 3376 3377 $indent -= 2; 3378 3379 print $fh " " x ($indent+$indent_offset); 3380# print $fh "}"; 3381 print $fh "\n"; 3382 } 3383 else 3384 { 3385 $indent -= 2; 3386 } 3387 3388 next; 3389 } 3390 elsif ( $l eq "{" ) 3391 { 3392# print $fh "{"; 3393 $inBlock = 1; 3394 $indent += 2; 3395 next; 3396 } 3397 3398 print $fh " " x ($indent+$indent_offset); 3399 print $fh $l; 3400 print $fh ':' if ( $l =~ /^ \s* (if | elif | else )/x ) ; 3401 print $fh "\n"; 3402 } 3403 3404 $indent = 0; 3405 print $fh "\n"; 3406 } 3407 ################################################## 3408 # Java / C# 3409 ################################################## 3410 elsif ( ($Target eq 'java') || ($Target eq 'csharp') ) 3411 { 3412 print $fh " " x ($indent+$indent_offset); 3413 3414 if ($is_global) 3415 { 3416 my $rtype = $IdSTRING{$Target}; 3417 $rtype = $IdBOOL{$Target} if $func =~ /isnan/; 3418 print $fh "public $rtype $func"; 3419 print $fh "()" unless $func =~ /$re_np/; 3420 print $fh "\n"; 3421 } 3422 elsif ( $func !~ /protected/ ) 3423 { 3424 print $fh "public void $func()\n" 3425 } 3426 else 3427 { 3428 print $fh "$func\n" 3429 } 3430 3431 for(my $i=0; $i < @{$funcRef}; $i++ ) 3432 { 3433 my $l = ${$funcRef}[$i]; 3434 $l =~ s/^\s*//; 3435 3436 if ( $l eq "}" ) 3437 { 3438 if ($inBlock) 3439 { 3440# print $fh " " x ($indent+$indent_offset); 3441 3442 $indent -= 2; 3443# print $fh "\n"; 3444 print $fh " " x ($indent+$indent_offset); 3445 print $fh "}"; 3446 print $fh "\n"; 3447 } 3448 else 3449 { 3450 $indent -= 2; 3451 } 3452 3453 next; 3454 } 3455 elsif ( $l eq "{" ) 3456 { 3457 print $fh " " x ($indent+$indent_offset); 3458 print $fh "{\n"; 3459 $inBlock = 1; 3460 $indent += 2; 3461 next; 3462 } 3463 3464 print $fh " " x ($indent+$indent_offset); 3465 print $fh $l; 3466 print $fh "\n"; 3467 } 3468 3469 $indent = 0; 3470 print $fh "\n"; 3471 } 3472 #################################################### 3473} 3474 3475sub writeCode 3476{ 3477 my ($file) = @_; 3478 my $cat = 'sbml'; 3479 3480 $cat = $1 if ( $file =~ m|/src/([^/]*)/| ); 3481 $file =~ s/.*\///; 3482 my $ofile = $file; 3483 3484 3485 ################################################## 3486 # Ruby/Python 3487 ################################################## 3488 if ( ( $Target eq 'ruby') || ( $Target eq 'python' ) ) 3489 { 3490 # to avoid duplicated file names 3491 $file =~ s/(CopyAndClone)/Annotation$1/ if ( $CurTestDir =~ /annotation/); 3492 $file =~ s/(CopyAndClone)/XML$1/ if ( $CurTestDir =~ /xml/); 3493 $file =~ s/(ReadFromFile[1-9])/Math$1/ if ( $CurTestDir =~ /math/); 3494 } 3495 3496 3497 ################################################## 3498 # Ruby 3499 ################################################## 3500 if ( $Target eq 'ruby') 3501 { 3502 $file =~ s/\.c$/.rb/; 3503 $file =~ s/\.cpp$/.rb/; 3504 } 3505 ################################################## 3506 # Python 3507 ################################################## 3508 if ( $Target eq 'python') 3509 { 3510 $file =~ s/\.c$/.py/; 3511 $file =~ s/\.cpp$/.py/; 3512 } 3513 ################################################## 3514 # Java 3515 ################################################## 3516 elsif ( $Target eq 'java') 3517 { 3518 $file =~ s/\.c$/.java/; 3519 $file =~ s/\.cpp$/.java/; 3520 } 3521 ################################################## 3522 # C# 3523 ################################################## 3524 elsif ( $Target eq 'csharp') 3525 { 3526 $file =~ s/\.c$/.cs/; 3527 $file =~ s/\.cpp$/.cs/; 3528 } 3529 ################################################## 3530 3531 open(FH, ">${OutputDir}/$file") or die "Can't write ${OutputDir}/$file : $!/$?"; 3532 3533 &writeHeader($file,*FH, $cat, $ofile); 3534 3535 ################################################## 3536 # Ruby 3537 ################################################## 3538 if ( $Target eq 'ruby' ) 3539 { 3540 # print macro definitions 3541 map { &printFuncDef($_, $MacroDef{$_}, *FH, 2 , 0) } sort keys %MacroDef; 3542 } 3543 ################################################## 3544 # Java 3545 ################################################## 3546 elsif ( $Target eq 'java' ) 3547 { 3548 # print macro definitions 3549 map { &printFuncDef($_, $MacroDef{$_}, *FH, 2, 1) } sort keys %MacroDef; 3550 } 3551 ################################################## 3552 # C# 3553 ################################################## 3554 elsif ( $Target eq 'csharp' ) 3555 { 3556 # print macro definitions 3557 map { &printFuncDef($_, $MacroDef{$_}, *FH, 4, 1) } sort keys %MacroDef; 3558 } 3559 ################################################## 3560 3561 (my $bname = $file) =~ s| \. .* ?$||gx; 3562 3563 # append a patch code 3564 print FH $patchClassTop{$Target}{$bname} if ( $patchClassTop{$Target}{$bname} ); 3565 3566 # append a patch code to the top of the corresponding function 3567 for ( keys %{ $patchFuncHead{$Target}{$bname} } ) 3568 { 3569 if ( defined( $FuncDef{$_} ) ) 3570 { 3571 my $tmp = shift @{ $FuncDef{$_} }; 3572 unshift ( @{ $FuncDef{$_} }, $patchFuncHead{$Target}{$bname}{$_} ); 3573 unshift ( @{ $FuncDef{$_} }, $tmp ); 3574 } 3575 } 3576 3577 # replace the function code with the corresponding path code 3578 for ( keys %{ $patchFuncReplace{$Target}{$bname} } ) 3579 { 3580 if ( defined( $FuncDef{$_} ) ) 3581 { 3582 @{ $FuncDef{$_} } = (); 3583 3584 # to avoid an invalid indent in Python 3585 push ( @{ $FuncDef{$_} }, "{" ); 3586 3587 push ( @{ $FuncDef{$_} }, $patchFuncReplace{$Target}{$bname}{$_} ); 3588 } 3589 } 3590 3591 # print test functions 3592 my $offset_funcdef = 2; 3593 $offset_funcdef = 4 if ( $Target eq 'csharp' ); 3594 map { &printFuncDef($_, $FuncDef{$_}, *FH, $offset_funcdef) unless ( defined( $IgnoreTestFunc{$_} ) ) } sort keys %FuncDef; 3595 3596 &writeFooter(*FH,$bname); 3597 3598 close(FH); 3599 3600 print "(converted) $ofile => ${OutputDir}/$file\n"; 3601 3602} 3603 3604sub writeHeader 3605{ 3606 my ($file, $fh, $cat, $ofile) = @_; 3607 my $cname = $file; 3608 3609 (my $lang = $Target) =~ s/^([a-z])/ uc $1 /xe; 3610 3611 my $brief = $FileProp{$ofile}{'brief'}; 3612 my @author; 3613 my $author; 3614 my $c; 3615 3616 $c = '#' if ( ($Target eq 'ruby') || ($Target eq 'python' ) ); 3617 $c = ' *' if ($Target eq 'java'); 3618 $c = '/// ' if ($Target eq 'csharp'); 3619 3620 $author = $c; 3621 $author .= " \@author Frank Bergmann (Csharp conversion)" if ($Target eq 'csharp'); 3622 3623 foreach ( @{ $FileProp{$ofile}{'author'} } ) 3624 { 3625 push ( @author, "$c \@author $_ \n"); 3626 } 3627 chomp( $author[length(@author)-1] ); 3628 3629 my $head; 3630 3631 $head = "/\*\n" if ($Target eq 'java'); 3632 $head = "$c\n" if ($Target eq 'python'); 3633 3634 $head .= <<"EOF"; 3635$c \@file $file 3636$c \@brief $brief 3637$author 3638$c \@author Akiya Jouraku ($lang conversion) 3639@author 3640$c 3641$c ====== WARNING ===== WARNING ===== WARNING ===== WARNING ===== WARNING ====== 3642$c 3643$c DO NOT EDIT THIS FILE. 3644$c 3645$c This file was generated automatically by converting the file located at 3646$c src/$cat/test/$ofile 3647$c using the conversion program dev/utilities/translateTests/translateTests.pl. 3648$c Any changes made here will be lost the next time the file is regenerated. 3649$c 3650$c ----------------------------------------------------------------------------- 3651$c This file is part of libSBML. Please visit http://sbml.org for more 3652$c information about SBML, and the latest version of libSBML. 3653$c 3654$c Copyright 2005-2010 California Institute of Technology. 3655$c Copyright 2002-2005 California Institute of Technology and 3656$c Japan Science and Technology Corporation. 3657$c 3658$c This library is free software; you can redistribute it and/or modify it 3659$c under the terms of the GNU Lesser General Public License as published by 3660$c the Free Software Foundation. A copy of the license agreement is provided 3661$c in the file named "LICENSE.txt" included with this software distribution 3662$c and also available online as http://sbml.org/software/libsbml/license.html 3663$c ----------------------------------------------------------------------------- 3664EOF 3665 3666 ################################################## 3667 # Ruby 3668 ################################################## 3669 if ( $Target eq 'ruby') 3670 { 3671 $cname =~ s/\.rb$//; 3672 ################################################## 3673 print $fh $head; 3674 print $fh "require 'test/unit'\n"; 3675 print $fh "require '$ModuleName{'ruby'}'\n\n"; 3676 ################################################## 3677 3678 # print patch for global variables/functions 3679 print $fh $patchGlobal{$Target}{$cname} if ( $patchGlobal{$Target}{$cname} ); 3680 3681 print $fh "class $cname < Test::Unit::TestCase\n\n" ; 3682 } 3683 ################################################## 3684 # Python 3685 ################################################## 3686 elsif ( $Target eq 'python') 3687 { 3688 $cname =~ s/\.py$//; 3689 ################################################## 3690 print $fh $head . "\n"; 3691 print $fh "import sys\n"; 3692 print $fh "import unittest\n"; 3693 print $fh "import $ModuleName{'python'}\n\n"; 3694 ################################################## 3695 3696 # print patch for global variables/functions 3697 print $fh $patchGlobal{$Target}{$cname} if ( $patchGlobal{$Target}{$cname} ); 3698 3699 # print macro definitions 3700 map { &printFuncDef($_, $MacroDef{$_}, *FH, 0, 1) } sort keys %MacroDef; 3701 3702 print $fh "\nclass $cname(unittest.TestCase):\n\n" ; 3703 for ( keys %GlobalVariable ) 3704 { 3705 next unless $_; 3706 print $fh " global $_\n"; 3707 print $fh " $_ = None\n"; 3708 } 3709 print $fh "\n"; 3710 } 3711 ################################################## 3712 # Java 3713 ################################################## 3714 elsif ( $Target eq 'java') 3715 { 3716 $cname =~ s/\.java$//; 3717 ################################################## 3718 print $fh $head . " \*/\n"; 3719 print $fh "\n"; 3720 print $fh "package " . $JavaPackage . ".$CurTestDir" . ";\n"; 3721 print $fh "\n"; 3722 print $fh "import org.sbml.$ModuleName{'java'}.*;\n\n"; 3723 print $fh "import java.io.File;\n"; 3724 print $fh "import java.lang.AssertionError;\n"; 3725# print $fh "import junit.framework.TestCase;\n\n"; 3726 ################################################## 3727 3728 # print patch for global variables/functions 3729 print $fh $patchGlobal{$Target}{$cname} if ( $patchGlobal{$Target}{$cname} ); 3730 3731# print $fh "public class $cname extends TestCase {\n\n" ; 3732 print $fh "\n"; 3733 print $fh "public class $cname {\n" ; 3734 3735 print $fh <<"EOF"; 3736 3737 static void assertTrue(boolean condition) throws AssertionError 3738 { 3739 if (condition == true) 3740 { 3741 return; 3742 } 3743 throw new AssertionError(); 3744 } 3745 3746 static void assertEquals(Object a, Object b) throws AssertionError 3747 { 3748 if ( (a == null) && (b == null) ) 3749 { 3750 return; 3751 } 3752 else if ( (a == null) || (b == null) ) 3753 { 3754 throw new AssertionError(); 3755 } 3756 else if (a.equals(b)) 3757 { 3758 return; 3759 } 3760 3761 throw new AssertionError(); 3762 } 3763 3764 static void assertNotEquals(Object a, Object b) throws AssertionError 3765 { 3766 if ( (a == null) && (b == null) ) 3767 { 3768 throw new AssertionError(); 3769 } 3770 else if ( (a == null) || (b == null) ) 3771 { 3772 return; 3773 } 3774 else if (a.equals(b)) 3775 { 3776 throw new AssertionError(); 3777 } 3778 } 3779 3780 static void assertEquals(boolean a, boolean b) throws AssertionError 3781 { 3782 if ( a == b ) 3783 { 3784 return; 3785 } 3786 throw new AssertionError(); 3787 } 3788 3789 static void assertNotEquals(boolean a, boolean b) throws AssertionError 3790 { 3791 if ( a != b ) 3792 { 3793 return; 3794 } 3795 throw new AssertionError(); 3796 } 3797 3798 static void assertEquals(int a, int b) throws AssertionError 3799 { 3800 if ( a == b ) 3801 { 3802 return; 3803 } 3804 throw new AssertionError(); 3805 } 3806 3807 static void assertNotEquals(int a, int b) throws AssertionError 3808 { 3809 if ( a != b ) 3810 { 3811 return; 3812 } 3813 throw new AssertionError(); 3814 } 3815EOF 3816 3817# # print patch for class variables/functions 3818# print $fh $patchClassTop{$Target}{$cname} if ( $patchClassTop{$Target}{$cname} ); 3819 3820 for ( keys %GlobalVariable ) 3821 { 3822 next unless $_; 3823 print $fh " private $_;\n"; 3824 } 3825 print $fh "\n"; 3826 } 3827 ################################################## 3828 # C# 3829 ################################################## 3830 elsif ( $Target eq 'csharp') 3831 { 3832 $cname =~ s/\.cs$//; 3833 ################################################## 3834 print $fh $head . "\n"; 3835 print $fh "\n"; 3836 print $fh "namespace $CSNamespace.$CurTestDir {\n\n"; 3837 print $fh " using $ModuleName{'csharp'};\n\n"; 3838 print $fh " using System;\n\n"; 3839 print $fh " using System.IO;\n\n"; 3840# print $fh "import junit.framework.TestCase;\n\n"; 3841 ################################################## 3842 3843 # print patch for global variables/functions 3844 print $fh $patchGlobal{$Target}{$cname} if ( $patchGlobal{$Target}{$cname} ); 3845 3846# print $fh "public class $cname extends TestCase {\n\n" ; 3847 print $fh " public class $cname {\n" ; 3848 print $fh " public class AssertionError : System.Exception \n"; 3849 print $fh " {\n"; 3850 print $fh " public AssertionError() : base()\n"; 3851 print $fh " {\n"; 3852 print $fh " \n"; 3853 print $fh " }\n"; 3854 print $fh " }\n"; 3855 print $fh "\n"; 3856 3857 print $fh <<"EOF"; 3858 3859 static void assertTrue(bool condition) 3860 { 3861 if (condition == true) 3862 { 3863 return; 3864 } 3865 throw new AssertionError(); 3866 } 3867 3868 static void assertEquals(object a, object b) 3869 { 3870 if ( (a == null) && (b == null) ) 3871 { 3872 return; 3873 } 3874 else if ( (a == null) || (b == null) ) 3875 { 3876 throw new AssertionError(); 3877 } 3878 else if (a.Equals(b)) 3879 { 3880 return; 3881 } 3882 3883 throw new AssertionError(); 3884 } 3885 3886 static void assertNotEquals(object a, object b) 3887 { 3888 if ( (a == null) && (b == null) ) 3889 { 3890 throw new AssertionError(); 3891 } 3892 else if ( (a == null) || (b == null) ) 3893 { 3894 return; 3895 } 3896 else if (a.Equals(b)) 3897 { 3898 throw new AssertionError(); 3899 } 3900 } 3901 3902 static void assertEquals(bool a, bool b) 3903 { 3904 if ( a == b ) 3905 { 3906 return; 3907 } 3908 throw new AssertionError(); 3909 } 3910 3911 static void assertNotEquals(bool a, bool b) 3912 { 3913 if ( a != b ) 3914 { 3915 return; 3916 } 3917 throw new AssertionError(); 3918 } 3919 3920 static void assertEquals(int a, int b) 3921 { 3922 if ( a == b ) 3923 { 3924 return; 3925 } 3926 throw new AssertionError(); 3927 } 3928 3929 static void assertNotEquals(int a, int b) 3930 { 3931 if ( a != b ) 3932 { 3933 return; 3934 } 3935 throw new AssertionError(); 3936 } 3937 3938EOF 3939 3940 3941# # print patch for class variables/functions 3942# print $fh $patchClassTop{$Target}{$cname} if ( $patchClassTop{$Target}{$cname} ); 3943 3944 for ( keys %GlobalVariable ) 3945 { 3946 next unless $_; 3947 print $fh " private $_;\n"; 3948 } 3949 print $fh "\n"; 3950 } 3951 ################################################## 3952} 3953 3954sub writeFooter 3955{ 3956 my ($fh,$bname) = @_; 3957 3958 3959 ################################################## 3960 # Ruby 3961 ################################################## 3962 if ( $Target eq 'ruby') 3963 { 3964 print $fh "end\n"; 3965 } 3966 ################################################## 3967 # Python 3968 ################################################## 3969 elsif ( $Target eq 'python') 3970 { 3971 my $tail = <<"EOF"; 3972def suite(): 3973 suite = unittest.TestSuite() 3974 suite.addTest(unittest.makeSuite($bname)) 3975 3976 return suite 3977 3978if __name__ == "__main__": 3979 if unittest.TextTestRunner(verbosity=1).run(suite()).wasSuccessful() : 3980 sys.exit(0) 3981 else: 3982 sys.exit(1) 3983EOF 3984 print $fh $tail; 3985 } 3986 ################################################## 3987 # Java 3988 ################################################## 3989 elsif ( $Target eq 'java') 3990 { 3991 my $tail = <<'EOF'; 3992 /** 3993 * Loads the SWIG-generated libSBML Java module when this class is 3994 * loaded, or reports a sensible diagnostic message about why it failed. 3995 */ 3996 static 3997 { 3998 String varname; 3999 String shlibname; 4000 4001 if (System.getProperty("mrj.version") != null) 4002 { 4003 varname = "DYLD_LIBRARY_PATH"; // We're on a Mac. 4004 shlibname = "libsbmlj.jnilib and/or libsbml.dylib"; 4005 } 4006 else 4007 { 4008 varname = "LD_LIBRARY_PATH"; // We're not on a Mac. 4009 shlibname = "libsbmlj.so and/or libsbml.so"; 4010 } 4011 4012 try 4013 { 4014 System.loadLibrary("sbmlj"); 4015 // For extra safety, check that the jar file is in the classpath. 4016 Class.forName("org.sbml.libsbml.libsbml"); 4017 } 4018 catch (SecurityException e) 4019 { 4020 e.printStackTrace(); 4021 System.err.println("Could not load the libSBML library files due to a"+ 4022 " security exception.\n"); 4023 System.exit(1); 4024 } 4025 catch (UnsatisfiedLinkError e) 4026 { 4027 e.printStackTrace(); 4028 System.err.println("Error: could not link with the libSBML library files."+ 4029 " It is likely\nyour " + varname + 4030 " environment variable does not include the directories\n"+ 4031 "containing the " + shlibname + " library files.\n"); 4032 System.exit(1); 4033 } 4034 catch (ClassNotFoundException e) 4035 { 4036 e.printStackTrace(); 4037 System.err.println("Error: unable to load the file libsbmlj.jar."+ 4038 " It is likely\nyour -classpath option and CLASSPATH" + 4039 " environment variable\n"+ 4040 "do not include the path to libsbmlj.jar.\n"); 4041 System.exit(1); 4042 } 4043 } 4044} 4045EOF 4046 print $fh $tail; 4047} 4048 ################################################## 4049 # C# 4050 ################################################## 4051 elsif ( $Target eq 'csharp') 4052 { 4053 my $tail = <<'EOF'; 4054 } 4055} 4056EOF 4057 print $fh $tail; 4058 } 4059} 4060 4061###################################################################### 4062# 4063# Patches 4064# 4065###################################################################### 4066 4067sub initPatch 4068{ 4069###################################################################### 4070# Ruby 4071###################################################################### 4072 4073if ($Target eq 'ruby' ) 4074{ 4075 4076#-------------------------------------------------- 4077 4078$patchFuncHead{'ruby'}{'TestReadSBML'}{'test_ReadSBML_line_col_numbers'} = <<'EOF'; 4079 setXMLParser 4080EOF 4081 4082#-------------------------------------------------- 4083 4084$patchClassTop{'ruby'}{'TestReadSBML'} = <<'EOF'; 4085 @@USE_LIBXML = 0 4086 @@USE_EXPAT = 0 4087 @@USE_XERCES = 0 4088 4089 def setXMLParser 4090 make_config = "../../../config/makefile-common-vars.mk" 4091 4092 File.foreach(make_config) do |line| 4093 @@USE_EXPAT = 1 if line =~ /^ USE_EXPAT \s* = \s* 1/x 4094 @@USE_LIBXML = 1 if line =~ /^ USE_LIBXML \s* = \s* 1/x 4095 @@USE_XERCES = 1 if line =~ /^ USE_XERCES \s* = \s* 1/x 4096 end 4097 end 4098 4099EOF 4100 4101#-------------------------------------------------- 4102 4103$patchClassTop{'ruby'}{'TestWriteSBML'} = <<'EOF'; 4104 def util_NaN 4105 z = 0.0 4106 return 0.0/z 4107 end 4108 4109 def util_PosInf 4110 z = 0.0 4111 return 1.0/z 4112 end 4113 4114 def util_NegInf 4115 z = 0.0 4116 return -1.0/z 4117 end 4118 4119 def equals(*x) 4120 case x.size 4121 when 2 4122 e, s = x 4123 return e == s 4124 when 1 4125 e, = x 4126 return e == @@oss.str() 4127 end 4128 end 4129 4130EOF 4131 4132$patchClassTop{'ruby'}{'TestXMLAttributes'} = $patchClassTop{'ruby'}{'TestWriteSBML'}; 4133$patchClassTop{'ruby'}{'TestWriteMathML'} = $patchClassTop{'ruby'}{'TestWriteSBML'}; 4134$patchClassTop{'ruby'}{'TestWriteL3SBML'} = $patchClassTop{'ruby'}{'TestWriteSBML'}; 4135 4136$patchClassTop{'ruby'}{'TestRDFAnnotation'} = $patchClassTop{'ruby'}{'TestWriteSBML'}; 4137$patchClassTop{'ruby'}{'TestRDFAnnotation2'} = $patchClassTop{'ruby'}{'TestWriteSBML'}; 4138 4139$patchClassTop{'ruby'}{'TestReadFromFile9'} = <<'EOF'; 4140 def isnan(x) 4141 return (x != x) 4142 end 4143EOF 4144 4145$patchClassTop{'ruby'}{'TestL3Compartment'} = $patchClassTop{'ruby'}{'TestReadFromFile9'}; 4146$patchClassTop{'ruby'}{'TestL3Unit'} = $patchClassTop{'ruby'}{'TestReadFromFile9'}; 4147$patchClassTop{'ruby'}{'TestL3Parameter'} = $patchClassTop{'ruby'}{'TestReadFromFile9'}; 4148$patchClassTop{'ruby'}{'TestL3Species'} = $patchClassTop{'ruby'}{'TestReadFromFile9'}; 4149$patchClassTop{'ruby'}{'TestL3SpeciesReference'} = $patchClassTop{'ruby'}{'TestReadFromFile9'}; 4150 4151#-------------------------------------------------- 4152 4153$patchClassTop{'ruby'}{'TestReadMathML'} = <<'EOF'; 4154 def util_isInf(*x) 4155 e, = x 4156 return ( e == util_PosInf() || e == util_NegInf() ) 4157 end 4158EOF 4159 4160$patchClassTop{'ruby'}{'TestReadMathML'} .= $patchClassTop{'ruby'}{'TestWriteSBML'}; 4161 4162#-------------------------------------------------- 4163 4164$patchClassTop{'ruby'}{'TestASTNode'} = <<'EOF'; 4165 @@DBL_EPSILON = 2.2204460492503131e-16 4166EOF 4167 4168$patchClassTop{'ruby'}{'TestL3Unit'} .= <<'EOF'; 4169 @@SBML_INT_MAX = 2147483647 4170EOF 4171 4172$patchClassTop{'ruby'}{'TestSBase_newSetters'} .= <<'EOF'; 4173 @@SBML_INT_MAX = 2147483647 4174EOF 4175 4176$patchClassTop{'ruby'}{'TestReadFromFile9'} .= <<'EOF'; 4177 @@SBML_INT_MAX = 2147483647 4178EOF 4179#-------------------------------------------------- 4180 4181$patchFuncReplace{'ruby'}{'TestWriteSBML'}{'test_WriteSBML_gzip'} = <<'EOF'; 4182 file = [ 4183 "../../../examples/sample-models/from-spec/level-2/algebraicrules.xml", 4184 "../../../examples/sample-models/from-spec/level-2/assignmentrules.xml", 4185 "../../../examples/sample-models/from-spec/level-2/boundarycondition.xml", 4186 "../../../examples/sample-models/from-spec/level-2/delay.xml", 4187 "../../../examples/sample-models/from-spec/level-2/dimerization.xml", 4188 "../../../examples/sample-models/from-spec/level-2/enzymekinetics.xml", 4189 "../../../examples/sample-models/from-spec/level-2/events.xml", 4190 "../../../examples/sample-models/from-spec/level-2/functiondef.xml", 4191 "../../../examples/sample-models/from-spec/level-2/multicomp.xml", 4192 "../../../examples/sample-models/from-spec/level-2/overdetermined.xml", 4193 "../../../examples/sample-models/from-spec/level-2/twodimensional.xml", 4194 "../../../examples/sample-models/from-spec/level-2/units.xml" 4195 ] 4196 gzfile = "test.xml.gz" 4197 file.each do |f| 4198 d = LibSBML::readSBML(f) 4199 assert( d != nil ) 4200 if not LibSBML::SBMLWriter::hasZlib() 4201 assert( LibSBML::writeSBML(d,gzfile) == 0 ) 4202 d = nil 4203 next 4204 end 4205 result = LibSBML::writeSBML(d,gzfile) 4206 assert_equal 1, result 4207 dg = LibSBML::readSBML(gzfile) 4208 assert( dg != nil ) 4209 assert( ( dg.toSBML() != d.toSBML() ) == false ) 4210 d = nil 4211 dg = nil 4212 end 4213 end 4214EOF 4215 4216$patchFuncReplace{'ruby'}{'TestWriteSBML'}{'test_WriteSBML_bzip2'} = $patchFuncReplace{'ruby'}{'TestWriteSBML'}{'test_WriteSBML_gzip'}; 4217$patchFuncReplace{'ruby'}{'TestWriteSBML'}{'test_WriteSBML_bzip2'} =~ s/gz/bz2/g; 4218$patchFuncReplace{'ruby'}{'TestWriteSBML'}{'test_WriteSBML_bzip2'} =~ s/hasZlib/hasBzip2/g; 4219 4220 4221$patchFuncReplace{'ruby'}{'TestWriteSBML'}{'test_WriteSBML_zip'} = $patchFuncReplace{'ruby'}{'TestWriteSBML'}{'test_WriteSBML_gzip'}; 4222$patchFuncReplace{'ruby'}{'TestWriteSBML'}{'test_WriteSBML_zip'} =~ s/gz/zip/g; 4223 4224 4225$patchFuncReplace{'ruby'}{'TestWriteL3SBML'}{'test_WriteL3SBML_gzip'} = $patchFuncReplace{'ruby'}{'TestWriteSBML'}{'test_WriteSBML_gzip'}; 4226$patchFuncReplace{'ruby'}{'TestWriteL3SBML'}{'test_WriteL3SBML_gzip'} =~ s/level-2/level-3/g; 4227 4228$patchFuncReplace{'ruby'}{'TestWriteL3SBML'}{'test_WriteL3SBML_bzip2'} = $patchFuncReplace{'ruby'}{'TestWriteSBML'}{'test_WriteSBML_bzip2'}; 4229$patchFuncReplace{'ruby'}{'TestWriteL3SBML'}{'test_WriteL3SBML_bzip2'} =~ s/level-2/level-3/g; 4230 4231$patchFuncReplace{'ruby'}{'TestWriteL3SBML'}{'test_WriteL3SBML_zip'} = $patchFuncReplace{'ruby'}{'TestWriteSBML'}{'test_WriteSBML_zip'}; 4232$patchFuncReplace{'ruby'}{'TestWriteL3SBML'}{'test_WriteL3SBML_zip'} =~ s/level-2/level-3/g; 4233 4234#-------------------------------------------------- 4235$patchClassTop{'ruby'}{'TestL3ModelHistory'} = <<'EOF'; 4236 def equals(*x) 4237 case x.size 4238 when 2 4239 e, s = x 4240 return e == s 4241 when 1 4242 e, = x 4243 return e == @@oss.str() 4244 end 4245 end 4246 4247EOF 4248 4249} 4250###################################################################### 4251# Python 4252###################################################################### 4253elsif ( $Target eq 'python' ) 4254{ 4255 4256#-------------------------------------------------- 4257 4258$patchFuncHead{'python'}{'TestReadSBML'}{'test_ReadSBML_line_col_numbers'} = <<'EOF'; 4259 setXMLParser() 4260EOF 4261 4262#-------------------------------------------------- 4263 4264$patchGlobal{'python'}{'TestReadSBML'} = <<'EOF'; 4265import re 4266 4267USE_LIBXML = 0 4268USE_EXPAT = 0 4269USE_XERCES = 0 4270 4271def setXMLParser(): 4272 make_config = "../../../config/makefile-common-vars.mk" 4273 4274 global USE_LIBXML 4275 global USE_EXPAT 4276 global USE_XERCES 4277 4278 re_expat = re.compile('^ USE_EXPAT \s* = \s* 1', re.X) 4279 re_libxml = re.compile('^ USE_LIBXML \s* = \s* 1', re.X) 4280 re_xerces = re.compile('^ USE_XERCES \s* = \s* 1', re.X) 4281 4282 f = open(make_config) 4283 for line in f: 4284 if re_expat.match(line) : USE_EXPAT = 1 4285 if re_libxml.match(line) : USE_LIBXML = 1 4286 if re_xerces.match(line) : USE_XERCES = 1 4287 4288def wrapString(s): 4289 return s 4290 pass 4291 4292EOF 4293 4294#-------------------------------------------------- 4295 4296$patchGlobal{'python'}{'TestWriteSBML'} = <<'EOF'; 4297def util_NaN(): 4298 z = 1e300 4299 z = z * z 4300 4301 return z - z 4302 4303def util_PosInf(): 4304 z = 1e300 4305 z = z * z 4306 4307 return z 4308 4309def util_NegInf(): 4310 z = 1e300 4311 z = z * z 4312 4313 return -z 4314 4315def wrapString(s): 4316 return s 4317 pass 4318 4319EOF 4320 4321$patchGlobal{'python'}{'TestXMLAttributes'} = $patchGlobal{'python'}{'TestWriteSBML'}; 4322$patchGlobal{'python'}{'TestWriteMathML'} = $patchGlobal{'python'}{'TestWriteSBML'}; 4323$patchGlobal{'python'}{'TestWriteL3SBML'} = $patchGlobal{'python'}{'TestWriteSBML'}; 4324 4325$patchGlobal{'python'}{'TestReadFromFile9'} = <<'EOF'; 4326def isnan(x): 4327 return (x != x) 4328 pass 4329EOF 4330 4331$patchGlobal{'python'}{'TestL3Compartment'} = $patchGlobal{'python'}{'TestReadFromFile9'}; 4332$patchGlobal{'python'}{'TestL3Unit'} = $patchGlobal{'python'}{'TestReadFromFile9'}; 4333$patchGlobal{'python'}{'TestL3Parameter'} = $patchGlobal{'python'}{'TestReadFromFile9'}; 4334$patchGlobal{'python'}{'TestL3Species'} = $patchGlobal{'python'}{'TestReadFromFile9'}; 4335$patchGlobal{'python'}{'TestL3SpeciesReference'} = $patchGlobal{'python'}{'TestReadFromFile9'}; 4336 4337$patchClassTop{'python'}{'TestWriteSBML'} = <<'EOF'; 4338 def equals(self, *x): 4339 if len(x) == 2: 4340 return x[0] == x[1] 4341 elif len(x) == 1: 4342 return x[0] == self.OSS.str() 4343 4344EOF 4345 4346$patchClassTop{'python'}{'TestL3ModelHistory'} = <<'EOF'; 4347 def equals(self, *x): 4348 if len(x) == 2: 4349 return x[0] == x[1] 4350 elif len(x) == 1: 4351 return x[0] == self.OSS.str() 4352 4353EOF 4354 4355$patchClassTop{'python'}{'TestWriteMathML'} = $patchClassTop{'python'}{'TestWriteSBML'}; 4356$patchClassTop{'python'}{'TestRDFAnnotation'} = $patchClassTop{'python'}{'TestWriteSBML'}; 4357$patchClassTop{'python'}{'TestRDFAnnotation2'} = $patchClassTop{'python'}{'TestWriteSBML'}; 4358$patchClassTop{'python'}{'TestWriteL3SBML'} = $patchClassTop{'python'}{'TestWriteSBML'}; 4359 4360$patchClassTop{'python'}{'TestSBMLConstructorException'} = <<'EOF'; 4361 currently_not_converted_by_ctest_converter = 1 4362 4363 4364EOF 4365 4366$patchClassTop{'python'}{'TestXMLErrorLog'} = <<'EOF'; 4367 currently_not_converted_by_ctest_converter = 1 4368 4369 4370EOF 4371 4372#-------------------------------------------------- 4373 4374$patchGlobal{'python'}{'TestReadMathML'} = <<'EOF'; 4375def util_isInf(*x): 4376 return ( (x[0] == util_PosInf()) or (x[0] == util_NegInf()) ) 4377 4378EOF 4379$patchGlobal{'python'}{'TestReadMathML'} .= $patchGlobal{'python'}{'TestWriteSBML'}; 4380 4381#-------------------------------------------------- 4382 4383$patchGlobal{'python'}{'TestSBase'} = <<'EOF'; 4384def wrapString(s): 4385 return s 4386 pass 4387 4388EOF 4389 4390$patchGlobal{'python'}{'TestXMLInputStream'} = $patchGlobal{'python'}{'TestSBase'}; 4391$patchGlobal{'python'}{'TestXMLOutputStream'} = $patchGlobal{'python'}{'TestSBase'}; 4392$patchGlobal{'python'}{'TestXMLNode'} = $patchGlobal{'python'}{'TestSBase'}; 4393$patchGlobal{'python'}{'TestRDFAnnotation'} = $patchGlobal{'python'}{'TestSBase'}; 4394$patchGlobal{'python'}{'TestRDFAnnotation2'} = $patchGlobal{'python'}{'TestSBase'}; 4395$patchGlobal{'python'}{'TestSBase_newSetters'} = $patchGlobal{'python'}{'TestSBase'}; 4396 4397#-------------------------------------------------- 4398 4399$patchGlobal{'python'}{'TestASTNode'} = <<'EOF'; 4400DBL_EPSILON = 2.2204460492503131e-16 4401 4402EOF 4403 4404$patchGlobal{'python'}{'TestL3Unit'} .= <<'EOF'; 4405SBML_INT_MAX = 2147483647 4406EOF 4407 4408$patchGlobal{'python'}{'TestSBase_newSetters'} .= <<'EOF'; 4409SBML_INT_MAX = 2147483647 4410EOF 4411 4412$patchGlobal{'python'}{'TestReadFromFile9'} .= <<'EOF'; 4413SBML_INT_MAX = 2147483647 4414EOF 4415#-------------------------------------------------- 4416 4417$patchFuncReplace{'python'}{'TestWriteSBML'}{'test_WriteSBML_gzip'} = <<'EOF'; 4418 file = [] 4419 file.append("../../../examples/sample-models/from-spec/level-2/algebraicrules.xml") 4420 file.append("../../../examples/sample-models/from-spec/level-2/assignmentrules.xml") 4421 file.append("../../../examples/sample-models/from-spec/level-2/boundarycondition.xml") 4422 file.append("../../../examples/sample-models/from-spec/level-2/delay.xml") 4423 file.append("../../../examples/sample-models/from-spec/level-2/dimerization.xml") 4424 file.append("../../../examples/sample-models/from-spec/level-2/enzymekinetics.xml") 4425 file.append("../../../examples/sample-models/from-spec/level-2/events.xml") 4426 file.append("../../../examples/sample-models/from-spec/level-2/functiondef.xml") 4427 file.append("../../../examples/sample-models/from-spec/level-2/multicomp.xml") 4428 file.append("../../../examples/sample-models/from-spec/level-2/overdetermined.xml") 4429 file.append("../../../examples/sample-models/from-spec/level-2/twodimensional.xml") 4430 file.append("../../../examples/sample-models/from-spec/level-2/units.xml") 4431 4432 gzfile = "test.xml.gz" 4433 for f in file: 4434 d = libsbml.readSBML(f) 4435 self.assert_( d != None ) 4436 if not libsbml.SBMLWriter.hasZlib(): 4437 self.assert_( libsbml.writeSBML(d,gzfile) == 0 ) 4438 d = None 4439 continue 4440 result = libsbml.writeSBML(d,gzfile) 4441 self.assertEqual( 1, result ) 4442 dg = libsbml.readSBML(gzfile) 4443 self.assert_( dg != None ) 4444 self.assert_( ( dg.toSBML() != d.toSBML() ) == False ) 4445 d = None 4446 dg = None 4447 pass 4448EOF 4449 4450$patchFuncReplace{'python'}{'TestWriteSBML'}{'test_WriteSBML_bzip2'} = $patchFuncReplace{'python'}{'TestWriteSBML'}{'test_WriteSBML_gzip'}; 4451$patchFuncReplace{'python'}{'TestWriteSBML'}{'test_WriteSBML_bzip2'} =~ s/gz/bz2/g; 4452$patchFuncReplace{'python'}{'TestWriteSBML'}{'test_WriteSBML_bzip2'} =~ s/hasZlib/hasBzip2/g; 4453 4454 4455$patchFuncReplace{'python'}{'TestWriteSBML'}{'test_WriteSBML_zip'} = $patchFuncReplace{'python'}{'TestWriteSBML'}{'test_WriteSBML_gzip'}; 4456$patchFuncReplace{'python'}{'TestWriteSBML'}{'test_WriteSBML_zip'} =~ s/gz/zip/g; 4457 4458 4459$patchFuncReplace{'python'}{'TestWriteL3SBML'}{'test_WriteL3SBML_gzip'} = $patchFuncReplace{'python'}{'TestWriteSBML'}{'test_WriteSBML_gzip'}; 4460$patchFuncReplace{'python'}{'TestWriteL3SBML'}{'test_WriteL3SBML_gzip'} =~ s/level-2/level-3/g; 4461 4462$patchFuncReplace{'python'}{'TestWriteL3SBML'}{'test_WriteL3SBML_bzip2'} = $patchFuncReplace{'python'}{'TestWriteSBML'}{'test_WriteSBML_bzip2'}; 4463$patchFuncReplace{'python'}{'TestWriteL3SBML'}{'test_WriteL3SBML_bzip2'} =~ s/level-2/level-3/g; 4464 4465$patchFuncReplace{'python'}{'TestWriteL3SBML'}{'test_WriteL3SBML_zip'} = $patchFuncReplace{'python'}{'TestWriteSBML'}{'test_WriteSBML_zip'}; 4466$patchFuncReplace{'python'}{'TestWriteL3SBML'}{'test_WriteL3SBML_zip'} =~ s/level-2/level-3/g; 4467 4468$patchGlobal{'python'}{'TestL3ModelHistory'} = <<'EOF'; 4469def wrapString(s): 4470 return s 4471 pass 4472 4473EOF 4474 4475 4476#-------------------------------------------------- 4477} 4478###################################################################### 4479# Java 4480###################################################################### 4481elsif ( $Target eq 'java' ) 4482{ 4483 4484#-------------------------------------------------- 4485 4486$patchFuncHead{'java'}{'TestReadSBML'}{'test_ReadSBML_line_col_numbers'} = <<'EOF'; 4487 setXMLParser(); 4488 4489EOF 4490 4491#-------------------------------------------------- 4492 4493$patchGlobal{'java'}{'TestReadSBML'} = <<'EOF'; 4494import java.util.regex.Pattern; 4495import java.util.regex.Matcher; 4496import java.io.FileInputStream; 4497import java.io.InputStreamReader; 4498import java.io.BufferedReader; 4499 4500EOF 4501#-------------------------------------------------- 4502 4503$patchClassTop{'java'}{'TestReadSBML'} = <<'EOF'; 4504 4505 private int USE_LIBXML = 0; 4506 private int USE_EXPAT = 0; 4507 private int USE_XERCES = 0; 4508 4509 public void setXMLParser() 4510 { 4511 String make_config = "../../../config/makefile-common-vars.mk"; 4512 4513 Pattern pt_expat = Pattern.compile("^USE_EXPAT\\s*=\\s*1"); 4514 Pattern pt_libxml = Pattern.compile("^USE_LIBXML\\s*=\\s*1"); 4515 Pattern pt_xerces = Pattern.compile("^USE_XERCES\\s*=\\s*1"); 4516 4517 try 4518 { 4519 FileInputStream fis = new FileInputStream(make_config); 4520 InputStreamReader ir = new InputStreamReader(fis); 4521 BufferedReader br = new BufferedReader(ir); 4522 4523 String line; 4524 while( (line = br.readLine()) != null) 4525 { 4526 Matcher m; 4527 4528 m = pt_libxml.matcher(line); 4529 if ( m.matches() ) 4530 { 4531 USE_LIBXML = 1; 4532 } 4533 4534 m = pt_expat.matcher(line); 4535 if ( m.matches() ) 4536 { 4537 USE_EXPAT = 1; 4538 } 4539 4540 m = pt_xerces.matcher(line); 4541 if ( m.matches() ) 4542 { 4543 USE_XERCES = 1; 4544 } 4545 } 4546 } 4547 catch (Exception e) 4548 { 4549 System.exit(1); 4550 } 4551 } 4552 4553EOF 4554 4555#-------------------------------------------------- 4556 4557$patchClassTop{'java'}{'TestWriteSBML'} = <<'EOF'; 4558 4559 public double util_NaN() 4560 { 4561 double z = 0.0; 4562 return 0.0/z; 4563 } 4564 4565 public double util_PosInf() 4566 { 4567 double z = 0.0; 4568 return 1.0/z; 4569 } 4570 4571 public double util_NegInf() 4572 { 4573 double z = 0.0; 4574 return -1.0/z; 4575 } 4576 4577 public boolean equals(String s1, String s2) 4578 { 4579 return s1.equals(s2); 4580 } 4581 4582EOF 4583 4584$patchClassTop{'java'}{'TestXMLAttributes'} = <<'EOF'; 4585 4586 public double util_NaN() 4587 { 4588 double z = 0.0; 4589 return 0.0/z; 4590 } 4591 4592 public double util_PosInf() 4593 { 4594 double z = 0.0; 4595 return 1.0/z; 4596 } 4597 4598 public double util_NegInf() 4599 { 4600 double z = 0.0; 4601 return -1.0/z; 4602 } 4603 4604EOF 4605 4606$patchClassTop{'java'}{'TestWriteMathML'} = $patchClassTop{'java'}{'TestWriteSBML'}; 4607 4608$patchClassTop{'java'}{'TestRDFAnnotation'} = $patchClassTop{'java'}{'TestWriteSBML'}; 4609$patchClassTop{'java'}{'TestRDFAnnotation2'} = $patchClassTop{'java'}{'TestWriteSBML'}; 4610$patchClassTop{'java'}{'TestReadFileFrom9'} = $patchClassTop{'java'}{'TestWriteSBML'}; 4611$patchClassTop{'java'}{'TestWriteL3SBML'} = $patchClassTop{'java'}{'TestWriteSBML'}; 4612 4613$patchClassTop{'java'}{'TestReadMathML'} = <<'EOF'; 4614 public boolean util_isInf(double x) 4615 { 4616 return ( (x == util_PosInf()) || (x == util_NegInf()) ); 4617 } 4618 4619EOF 4620$patchClassTop{'java'}{'TestReadMathML'} .= $patchClassTop{'java'}{'TestXMLAttributes'}; 4621 4622$patchClassTop{'java'}{'TestReadFromFile9'} = <<'EOF'; 4623 public boolean isnan(double x) 4624 { 4625 return (x != x); 4626 } 4627 4628EOF 4629 4630$patchClassTop{'java'}{'TestL3Compartment'} = $patchClassTop{'java'}{'TestReadFromFile9'}; 4631$patchClassTop{'java'}{'TestL3Unit'} = $patchClassTop{'java'}{'TestReadFromFile9'}; 4632$patchClassTop{'java'}{'TestL3Parameter'} = $patchClassTop{'java'}{'TestReadFromFile9'}; 4633$patchClassTop{'java'}{'TestL3Species'} = $patchClassTop{'java'}{'TestReadFromFile9'}; 4634$patchClassTop{'java'}{'TestL3SpeciesReference'} = $patchClassTop{'java'}{'TestReadFromFile9'}; 4635 4636#-------------------------------------------------- 4637 4638$patchClassTop{'java'}{'TestASTNode'} = <<'EOF'; 4639 public static final double DBL_EPSILON = 2.2204460492503131e-016; 4640 4641EOF 4642 4643$patchClassTop{'java'}{'TestL3Unit'} .= <<'EOF'; 4644 public static final int SBML_INT_MAX = 2147483647; 4645EOF 4646 4647$patchClassTop{'java'}{'TestSBase_newSetters'} .= <<'EOF'; 4648 public static final int SBML_INT_MAX = 2147483647; 4649EOF 4650 4651$patchClassTop{'java'}{'TestReadFromFile9'} .= <<'EOF'; 4652 public static final int SBML_INT_MAX = 2147483647; 4653EOF 4654#-------------------------------------------------- 4655 4656$patchFuncReplace{'java'}{'TestWriteSBML'}{'test_WriteSBML_gzip'} = <<'EOF'; 4657 4658 int filenum = 12; 4659 String file[] = { 4660 "../../../examples/sample-models/from-spec/level-2/algebraicrules.xml", 4661 "../../../examples/sample-models/from-spec/level-2/assignmentrules.xml", 4662 "../../../examples/sample-models/from-spec/level-2/boundarycondition.xml", 4663 "../../../examples/sample-models/from-spec/level-2/delay.xml", 4664 "../../../examples/sample-models/from-spec/level-2/dimerization.xml", 4665 "../../../examples/sample-models/from-spec/level-2/enzymekinetics.xml", 4666 "../../../examples/sample-models/from-spec/level-2/events.xml", 4667 "../../../examples/sample-models/from-spec/level-2/functiondef.xml", 4668 "../../../examples/sample-models/from-spec/level-2/multicomp.xml", 4669 "../../../examples/sample-models/from-spec/level-2/overdetermined.xml", 4670 "../../../examples/sample-models/from-spec/level-2/twodimensional.xml", 4671 "../../../examples/sample-models/from-spec/level-2/units.xml" 4672 }; 4673 String gzfile = "test.xml.gz"; 4674 for(int i = 0; i < filenum; i++) 4675 { 4676 SBMLDocument d = libsbml.readSBML(file[i]); 4677 assertTrue( d != null ); 4678 if (! SBMLWriter.hasZlib()) 4679 { 4680 assertTrue( libsbml.writeSBML(d, gzfile) == 0 ); 4681 d = null; 4682 continue; 4683 } 4684 boolean result = (libsbml.writeSBML(d, gzfile) != 0); 4685 assertEquals( true, result ); 4686 SBMLDocument dg = libsbml.readSBML(gzfile); 4687 assertTrue( dg != null ); 4688 assertTrue( !d.toSBML().equals(dg.toSBML()) == false ); 4689 d = null; 4690 dg = null; 4691 } 4692 } 4693EOF 4694 4695$patchFuncReplace{'java'}{'TestWriteSBML'}{'test_WriteSBML_bzip2'} = $patchFuncReplace{'java'}{'TestWriteSBML'}{'test_WriteSBML_gzip'}; 4696$patchFuncReplace{'java'}{'TestWriteSBML'}{'test_WriteSBML_bzip2'} =~ s/gz/bz2/g; 4697$patchFuncReplace{'java'}{'TestWriteSBML'}{'test_WriteSBML_bzip2'} =~ s/hasZlib/hasBzip2/g; 4698 4699 4700$patchFuncReplace{'java'}{'TestWriteSBML'}{'test_WriteSBML_zip'} = $patchFuncReplace{'java'}{'TestWriteSBML'}{'test_WriteSBML_gzip'}; 4701$patchFuncReplace{'java'}{'TestWriteSBML'}{'test_WriteSBML_zip'} =~ s/gz/zip/g; 4702 4703 4704$patchFuncReplace{'java'}{'TestWriteL3SBML'}{'test_WriteL3SBML_gzip'} = $patchFuncReplace{'java'}{'TestWriteSBML'}{'test_WriteSBML_gzip'}; 4705$patchFuncReplace{'java'}{'TestWriteL3SBML'}{'test_WriteL3SBML_gzip'} =~ s/level-2/level-3/g; 4706 4707$patchFuncReplace{'java'}{'TestWriteL3SBML'}{'test_WriteL3SBML_bzip2'} = $patchFuncReplace{'java'}{'TestWriteSBML'}{'test_WriteSBML_bzip2'}; 4708$patchFuncReplace{'java'}{'TestWriteL3SBML'}{'test_WriteL3SBML_bzip2'} =~ s/level-2/level-3/g; 4709 4710$patchFuncReplace{'java'}{'TestWriteL3SBML'}{'test_WriteL3SBML_zip'} = $patchFuncReplace{'java'}{'TestWriteSBML'}{'test_WriteSBML_zip'}; 4711$patchFuncReplace{'java'}{'TestWriteL3SBML'}{'test_WriteL3SBML_zip'} =~ s/level-2/level-3/g; 4712 4713#-------------------------------------------------- 4714 4715$patchClassTop{'java'}{'TestL3ModelHistory'} = <<'EOF'; 4716 4717 public boolean equals(String s1, String s2) 4718 { 4719 return s1.equals(s2); 4720 } 4721 4722EOF 4723 4724 4725#-------------------------------------------------- 4726} 4727###################################################################### 4728# C# 4729###################################################################### 4730elsif ( $Target eq 'csharp' ) 4731{ 4732 4733#-------------------------------------------------- 4734 4735$patchFuncHead{'csharp'}{'TestReadSBML'}{'test_ReadSBML_line_col_numbers'} = <<'EOF'; 4736 //setXMLParser(); 4737EOF 4738 4739#-------------------------------------------------- 4740 4741#$patchGlobal{'csharp'}{'TestReadSBML'} = <<'EOF'; 4742#using System.Xml; 4743#EOF 4744 4745#-------------------------------------------------- 4746 4747$patchClassTop{'csharp'}{'TestReadSBML'} = <<'EOF'; 4748 4749 private int USE_LIBXML = 0; 4750 private int USE_EXPAT = 0; 4751 private int USE_XERCES = 0; 4752 4753EOF 4754 4755#-------------------------------------------------- 4756 4757$patchClassTop{'csharp'}{'TestWriteSBML'} = <<'EOF'; 4758 4759 public double util_NaN() 4760 { 4761 double z = 0.0; 4762 return 0.0/z; 4763 } 4764 4765 public double util_PosInf() 4766 { 4767 double z = 0.0; 4768 return 1.0/z; 4769 } 4770 4771 public double util_NegInf() 4772 { 4773 double z = 0.0; 4774 return -1.0/z; 4775 } 4776 4777// public bool equals(string s) 4778// { 4779// return s == OSS.str(); 4780// } 4781 4782 public bool equals(string s1, string s2) 4783 { 4784 return (s1 ==s2); 4785 } 4786 4787EOF 4788 4789 4790$patchClassTop{'csharp'}{'TestXMLAttributes'} = <<'EOF'; 4791 4792 public double util_NaN() 4793 { 4794 double z = 0.0; 4795 return 0.0/z; 4796 } 4797 4798 public double util_PosInf() 4799 { 4800 double z = 0.0; 4801 return 1.0/z; 4802 } 4803 4804 public double util_NegInf() 4805 { 4806 double z = 0.0; 4807 return -1.0/z; 4808 } 4809 4810EOF 4811 4812 4813$patchClassTop{'csharp'}{'TestWriteMathML'} = $patchClassTop{'csharp'}{'TestWriteSBML'}; 4814 4815$patchClassTop{'csharp'}{'TestRDFAnnotation'} = $patchClassTop{'csharp'}{'TestWriteSBML'}; 4816$patchClassTop{'csharp'}{'TestRDFAnnotation2'} = $patchClassTop{'csharp'}{'TestWriteSBML'}; 4817 4818$patchClassTop{'csharp'}{'TestReadFileFrom9'} = $patchClassTop{'csharp'}{'TestWriteSBML'}; 4819$patchClassTop{'csharp'}{'TestWriteL3SBML'} = $patchClassTop{'csharp'}{'TestWriteSBML'}; 4820 4821$patchClassTop{'csharp'}{'TestReadMathML'} = <<'EOF'; 4822 public bool util_isInf(double x) 4823 { 4824 return ( (x == util_PosInf()) || (x == util_NegInf()) ); 4825 } 4826 4827EOF 4828$patchClassTop{'csharp'}{'TestReadMathML'} .= $patchClassTop{'csharp'}{'TestXMLAttributes'}; 4829 4830$patchClassTop{'csharp'}{'TestReadFromFile9'} = <<'EOF'; 4831 public bool isnan(double x) 4832 { 4833 return (x != x); 4834 } 4835 4836EOF 4837 4838$patchClassTop{'csharp'}{'TestL3Compartment'} = $patchClassTop{'csharp'}{'TestReadFromFile9'}; 4839$patchClassTop{'csharp'}{'TestL3Unit'} = $patchClassTop{'csharp'}{'TestReadFromFile9'}; 4840$patchClassTop{'csharp'}{'TestL3Parameter'} = $patchClassTop{'csharp'}{'TestReadFromFile9'}; 4841$patchClassTop{'csharp'}{'TestL3Species'} = $patchClassTop{'csharp'}{'TestReadFromFile9'}; 4842$patchClassTop{'csharp'}{'TestL3SpeciesReference'} = $patchClassTop{'csharp'}{'TestReadFromFile9'}; 4843 4844 4845#-------------------------------------------------- 4846 4847$patchClassTop{'csharp'}{'TestASTNode'} = <<'EOF'; 4848 private const double DBL_EPSILON = 2.2204460492503131e-016; 4849 4850EOF 4851 4852$patchClassTop{'csharp'}{'TestL3Unit'} .= <<'EOF'; 4853 private const int SBML_INT_MAX = 2147483647; 4854EOF 4855 4856$patchClassTop{'csharp'}{'TestSBase_newSetters'} .= <<'EOF'; 4857 private const int SBML_INT_MAX = 2147483647; 4858EOF 4859 4860$patchClassTop{'csharp'}{'TestReadFromFile9'} .= <<'EOF'; 4861 private const int SBML_INT_MAX = 2147483647; 4862EOF 4863#-------------------------------------------------- 4864 4865$patchFuncReplace{'csharp'}{'TestWriteSBML'}{'test_WriteSBML_gzip'} = <<'EOF'; 4866 4867 uint filenum = 12; 4868 string[] file = { 4869 "../../../examples/sample-models/from-spec/level-2/algebraicrules.xml", 4870 "../../../examples/sample-models/from-spec/level-2/assignmentrules.xml", 4871 "../../../examples/sample-models/from-spec/level-2/boundarycondition.xml", 4872 "../../../examples/sample-models/from-spec/level-2/delay.xml", 4873 "../../../examples/sample-models/from-spec/level-2/dimerization.xml", 4874 "../../../examples/sample-models/from-spec/level-2/enzymekinetics.xml", 4875 "../../../examples/sample-models/from-spec/level-2/events.xml", 4876 "../../../examples/sample-models/from-spec/level-2/functiondef.xml", 4877 "../../../examples/sample-models/from-spec/level-2/multicomp.xml", 4878 "../../../examples/sample-models/from-spec/level-2/overdetermined.xml", 4879 "../../../examples/sample-models/from-spec/level-2/twodimensional.xml", 4880 "../../../examples/sample-models/from-spec/level-2/units.xml" 4881 }; 4882 string gzfile = "test.xml.gz"; 4883 for(uint i = 0; i < filenum; i++) 4884 { 4885 SBMLDocument d = libsbml.readSBML(file[i]); 4886 assertTrue( d != null ); 4887 if (! SBMLWriter.hasZlib()) 4888 { 4889 assertTrue( libsbml.writeSBML(d, gzfile) == 0 ); 4890 d = null; 4891 continue; 4892 } 4893 int result = libsbml.writeSBML(d, gzfile); 4894 assertTrue( result != 0); 4895 SBMLDocument dg = libsbml.readSBML(gzfile); 4896 assertTrue( dg != null ); 4897 assertTrue( ( dg.toSBML() != d.toSBML() ) == false ); 4898 d = null; 4899 dg = null; 4900 } 4901 } 4902EOF 4903 4904$patchFuncReplace{'csharp'}{'TestWriteSBML'}{'test_WriteSBML_bzip2'} = $patchFuncReplace{'csharp'}{'TestWriteSBML'}{'test_WriteSBML_gzip'}; 4905$patchFuncReplace{'csharp'}{'TestWriteSBML'}{'test_WriteSBML_bzip2'} =~ s/gz/bz2/g; 4906$patchFuncReplace{'csharp'}{'TestWriteSBML'}{'test_WriteSBML_bzip2'} =~ s/hasZlib/hasBzip2/g; 4907 4908 4909$patchFuncReplace{'csharp'}{'TestWriteSBML'}{'test_WriteSBML_zip'} = $patchFuncReplace{'csharp'}{'TestWriteSBML'}{'test_WriteSBML_gzip'}; 4910$patchFuncReplace{'csharp'}{'TestWriteSBML'}{'test_WriteSBML_zip'} =~ s/gz/zip/g; 4911 4912 4913$patchFuncReplace{'csharp'}{'TestWriteL3SBML'}{'test_WriteL3SBML_gzip'} = $patchFuncReplace{'csharp'}{'TestWriteSBML'}{'test_WriteSBML_gzip'}; 4914$patchFuncReplace{'csharp'}{'TestWriteL3SBML'}{'test_WriteL3SBML_gzip'} =~ s/level-2/level-3/g; 4915 4916$patchFuncReplace{'csharp'}{'TestWriteL3SBML'}{'test_WriteL3SBML_bzip2'} = $patchFuncReplace{'csharp'}{'TestWriteSBML'}{'test_WriteSBML_bzip2'}; 4917$patchFuncReplace{'csharp'}{'TestWriteL3SBML'}{'test_WriteL3SBML_bzip2'} =~ s/level-2/level-3/g; 4918 4919$patchFuncReplace{'csharp'}{'TestWriteL3SBML'}{'test_WriteL3SBML_zip'} = $patchFuncReplace{'csharp'}{'TestWriteSBML'}{'test_WriteSBML_zip'}; 4920$patchFuncReplace{'csharp'}{'TestWriteL3SBML'}{'test_WriteL3SBML_zip'} =~ s/level-2/level-3/g; 4921 4922#-------------------------------------------------- 4923$patchClassTop{'csharp'}{'TestL3ModelHistory'} = <<'EOF'; 4924 4925 public bool equals(string s1, string s2) 4926 { 4927 return (s1 ==s2); 4928 } 4929 4930EOF 4931 4932} 4933 4934###################################################################### 4935 4936 4937} 4938 4939 4940 4941