]> git.donarmstrong.com Git - perltidy.git/commitdiff
added random parameter test script
authorSteve Hancock <perltidy@users.sourceforge.net>
Sat, 5 Sep 2020 23:22:40 +0000 (16:22 -0700)
committerSteve Hancock <perltidy@users.sourceforge.net>
Sat, 5 Sep 2020 23:22:40 +0000 (16:22 -0700)
t/snippets/perltidy_random_parameters.pl [new file with mode: 0755]

diff --git a/t/snippets/perltidy_random_parameters.pl b/t/snippets/perltidy_random_parameters.pl
new file mode 100755 (executable)
index 0000000..a44684d
--- /dev/null
@@ -0,0 +1,735 @@
+#!/usr/bin/perl -w
+use strict;
+use warnings;
+
+# This program was written to stress-test perltidy by running it repeatedly
+# with random parameters.  Testing perltidy on random scripts has always been
+# easy. You just collect a bunch of scripts in a directory and use
+
+#  perltidy *
+
+# But it is harder to test a variety of parameters, looking for problems with
+# their interactions.  That is what this script does.
+# I typically run it in the background from a bash script, something like this
+# nohup nice -n19 perltidy_random_parameters.pl $filename $number
+
+# TODO:
+# - This currently runs the perltidy binary.  Add an option to run call the
+#   module directly.
+# - Add additional garbage strings
+# - The parameters are hardwired but could be obtained directly from perltidy
+#   so that they are always up to date.
+
+my $usage = <<EOM;
+Run perltidy repeatedly on a selected file with randomly generated parameters:
+
+    perltidy_random_parameters ifile Num
+
+ifile is the name of a perl script to be formatted
+Num is the number of times, default 1000;
+
+You can stop the run any time by creating a file "stop.now"
+EOM
+
+my $ifile          = $ARGV[0];
+my $ifile_original = $ifile;
+my $max_cases      = $ARGV[1];
+if ( !$ifile || $max_cases <= 0 ) { die "$usage" }
+my $stop_file = 'stop.now';
+if ( -e $stop_file ) { unlink $stop_file }
+my $ifile_size = -s $ifile;
+
+# Set this flag to have each run format the output of the previous
+# run instead of formatting the original file.
+my $CHAIN_MODE = 1;
+
+my $case                  = "000";
+my $error_count           = 0;
+my $missing_ofile_count   = 0;
+my $missing_chkfile_count = 0;
+my ( $ofile_size_min,   $ofile_size_max );
+my ( $ofile_case_min,   $ofile_case_max );
+my ( $chkfile_size_min, $chkfile_size_max );
+my ( $chkfile_case_min, $chkfile_case_max );
+my $error_flag    = 0;
+my $restart_count = 0;
+
+for ( 1 .. $max_cases ) {
+    $case += 1;
+    print STDERR "\n-----\nCase: $case\n";
+    print STDOUT "\n-----\nCase: $case\n";
+    my $profile            = "profile.$case";
+    my $rrandom_parameters = get_random_parameters();
+    open OUT, ">", $profile || die "cannot open $profile: $!\n";
+    foreach ( @{$rrandom_parameters} ) {
+        print OUT "$_\n";
+    }
+    close OUT;
+    my $ofile   = "ofile.$case";
+    my $chkfile = "chkfile.$case";
+    system "perltidy < $ifile > $ofile -pro=$profile";
+    my $efile   = "perltidy.ERR";
+    my $logfile = "perltidy.LOG";
+    if ( -e $efile )   { rename $efile,   "ERR.$case" }
+    if ( -e $logfile ) { rename $logfile, "LOG.$case" }
+
+    if ( !-e $ofile ) {
+        print STDERR "**Warning** missing output $ofile\n";
+        $missing_ofile_count++;
+        $error_flag = 1;
+    }
+
+    else {
+        my $ofile_size = -s $ofile;
+        if ( !defined($ofile_size_min) ) {
+            $ofile_size_min = $ofile_size_max = $ofile_size;
+            $ofile_case_min = $ofile_case_max = $ofile;
+        }
+        else {
+            if ( $ofile_size < $ofile_size_min ) {
+                $ofile_size_min = $ofile_size;
+                $ofile_case_min = $ofile;
+            }
+            if ( $ofile_size > $ofile_size_max ) {
+                $ofile_size_max = $ofile_size;
+                $ofile_case_max = $ofile;
+            }
+        }
+    }
+
+    # run perltidy on the output to see if it can be reformatted
+    # without errors
+    system "perltidy < $ofile > $chkfile";
+    my $err;
+    if ( -e $efile ) {
+        rename $efile, "$chkfile.ERR";
+        print STDERR "**Error reformatting** see $chkfile.ERR\n";
+        $error_count++;
+        $err = 1;
+    }
+    if ( !-e $chkfile ) {
+        print STDERR "**Warning** missing checkfile output $chkfile\n";
+        $missing_chkfile_count++;
+        $err = 1;
+    }
+    else {
+        my $chkfile_size = -s $chkfile;
+        if ( !defined($chkfile_size_min) ) {
+            $chkfile_size_min = $chkfile_size_max = $chkfile_size;
+            $chkfile_case_min = $chkfile_case_max = $chkfile;
+        }
+        else {
+            if ( $chkfile_size < $chkfile_size_min ) {
+                $chkfile_size_min = $chkfile_size;
+                $chkfile_case_min = $chkfile;
+            }
+            if ( $chkfile_size > $chkfile_size_max ) {
+                $chkfile_size_max = $chkfile_size;
+                $chkfile_case_max = $chkfile;
+            }
+        }
+    }
+
+    if ($CHAIN_MODE) {
+        $ifile = $err ? $ifile_original : $ofile;
+        $restart_count++ if ($err);
+    }
+
+    if ( -e $stop_file ) {
+        print STDERR "$stop_file seen; exiting\n";
+    }
+}
+
+# Report results
+my $mode =
+  $CHAIN_MODE ? "chain mode, $restart_count restarts" : 'non-chain mode';
+print STDERR <<EOM;
+Run Summary:
+$ifile_original: starting input file
+running in $mode
+$error_count files had errors when reformatted
+$missing_ofile_count output files were missing 
+$missing_chkfile_count check output files were missing
+
+Size of test file: $ifile_size
+EOM
+
+print STDERR <<EOM if ( defined($ofile_size_min) );
+Minimum output size: $ofile_size_min for case $ofile_case_min
+Maximum output size: $ofile_size_max for case $ofile_case_max
+EOM
+
+print STDERR <<EOM if ( defined($chkfile_size_min) );
+Minimum rerun size: $chkfile_size_min for case $chkfile_case_min
+Maximum rerun size: $chkfile_size_max for case $chkfile_case_max
+EOM
+
+print STDERR <<EOM;
+
+Be sure to search for 'unitialized' in STDERR
+EOM
+
+sub get_random_parameters {
+
+    # return a set of random parameters for perltidy
+    my @random_parameters;
+
+    # Created with perltidy --dump-long-names
+
+    # Command line long names (passed to GetOptions)
+    #---------------------------------------------------------------
+    # here is a summary of the Getopt codes:
+    # <none> does not take an argument
+    # =s takes a mandatory string
+    # :s takes an optional string
+    # =i takes a mandatory integer
+    # :i takes an optional integer
+    # ! does not take an argument and may be negated
+    #  i.e., -foo and -nofoo are allowed
+    # a double dash signals the end of the options list
+    #
+    #---------------------------------------------------------------
+    my @parameters = qw(
+      DEBUG!
+      add-newlines!
+      add-semicolons!
+      add-whitespace!
+      assert-tidy!
+      assert-untidy!
+      backlink=s
+      backup-and-modify-in-place!
+      backup-file-extension=s
+      blank-lines-after-opening-block-list=s
+      blank-lines-after-opening-block=i
+      blank-lines-before-closing-block-list=s
+      blank-lines-before-closing-block=i
+      blank-lines-before-packages=i
+      blank-lines-before-subs=i
+      blanks-before-blocks!
+      blanks-before-comments!
+      block-brace-tightness=i
+      block-brace-vertical-tightness-list=s
+      block-brace-vertical-tightness=i
+      brace-left-and-indent!
+      brace-left-and-indent-list=s
+      brace-tightness=i
+      brace-vertical-tightness-closing=i
+      brace-vertical-tightness=i
+      break-after-all-operators!
+      break-at-old-attribute-breakpoints!
+      break-at-old-comma-breakpoints!
+      break-at-old-keyword-breakpoints!
+      break-at-old-logical-breakpoints!
+      break-at-old-method-breakpoints!
+      break-at-old-semicolon-breakpoints!
+      break-at-old-ternary-breakpoints!
+      break-before-all-operators!
+      cachedir=s
+      character-encoding=s
+      check-syntax!
+      closing-brace-indentation=i
+      closing-paren-indentation=i
+      closing-side-comment-else-flag=i
+      closing-side-comment-interval=i
+      closing-side-comment-list=s
+      closing-side-comment-maximum-text=i
+      closing-side-comment-prefix=s
+      closing-side-comment-warnings!
+      closing-side-comments!
+      closing-side-comments-balanced!
+      closing-square-bracket-indentation=i
+      closing-token-indentation=i
+      comma-arrow-breakpoints=i
+      continuation-indentation=i
+      cuddled-block-list-exclusive!
+      cuddled-block-list=s
+      cuddled-break-option=i
+      cuddled-else!
+      default-tabsize=i
+      delete-block-comments!
+      delete-closing-side-comments!
+      delete-old-newlines!
+      delete-old-whitespace!
+      delete-pod!
+      delete-semicolons!
+      delete-side-comments!
+      dump-cuddled-block-list!
+      dump-defaults!
+      dump-long-names!
+      dump-options!
+      dump-profile!
+      dump-short-names!
+      dump-token-types!
+      dump-want-left-space!
+      dump-want-right-space!
+      entab-leading-whitespace=i
+      extended-syntax!
+      file-size-order!
+      fixed-position-side-comment=i
+      force-read-binary!
+      format-skipping!
+      format-skipping-begin=s
+      format-skipping-end=s
+      format=s
+      frames!
+      fuzzy-line-length!
+      hanging-side-comments!
+      help
+      html!
+      html-bold-bareword!
+      html-bold-colon!
+      html-bold-comma!
+      html-bold-comment!
+      html-bold-here-doc-target!
+      html-bold-here-doc-text!
+      html-bold-identifier!
+      html-bold-keyword!
+      html-bold-label!
+      html-bold-numeric!
+      html-bold-paren!
+      html-bold-pod-text!
+      html-bold-punctuation!
+      html-bold-quote!
+      html-bold-semicolon!
+      html-bold-structure!
+      html-bold-subroutine!
+      html-bold-v-string!
+      html-color-background=s
+      html-color-bareword=s
+      html-color-colon=s
+      html-color-comma=s
+      html-color-comment=s
+      html-color-here-doc-target=s
+      html-color-here-doc-text=s
+      html-color-identifier=s
+      html-color-keyword=s
+      html-color-label=s
+      html-color-numeric=s
+      html-color-paren=s
+      html-color-pod-text=s
+      html-color-punctuation=s
+      html-color-quote=s
+      html-color-semicolon=s
+      html-color-structure=s
+      html-color-subroutine=s
+      html-color-v-string=s
+      html-entities!
+      html-italic-bareword!
+      html-italic-colon!
+      html-italic-comma!
+      html-italic-comment!
+      html-italic-here-doc-target!
+      html-italic-here-doc-text!
+      html-italic-identifier!
+      html-italic-keyword!
+      html-italic-label!
+      html-italic-numeric!
+      html-italic-paren!
+      html-italic-pod-text!
+      html-italic-punctuation!
+      html-italic-quote!
+      html-italic-semicolon!
+      html-italic-structure!
+      html-italic-subroutine!
+      html-italic-v-string!
+      html-line-numbers
+      html-linked-style-sheet=s
+      html-pre-only
+      html-src-extension=s
+      html-table-of-contents!
+      html-toc-extension=s
+      htmlroot=s
+      ignore-old-breakpoints!
+      ignore-side-comment-lengths!
+      indent-block-comments!
+      indent-closing-brace!
+      indent-columns=i
+      indent-spaced-block-comments!
+      iterations=i
+      keep-interior-semicolons!
+      keep-old-blank-lines=i
+      keyword-group-blanks-after=i
+      keyword-group-blanks-before=i
+      keyword-group-blanks-delete!
+      keyword-group-blanks-inside!
+      keyword-group-blanks-list=s
+      keyword-group-blanks-repeat-count=i
+      keyword-group-blanks-size=s
+      keyword-paren-inner-tightness-list=s
+      keyword-paren-inner-tightness=i
+      libpods=s
+      line-up-parentheses!
+      logfile!
+      logfile-gap:i
+      logical-padding!
+      long-block-line-count=i
+      look-for-autoloader!
+      look-for-hash-bang!
+      look-for-selfloader!
+      maximum-consecutive-blank-lines=i
+      maximum-fields-per-table=i
+      maximum-line-length=i
+      memoize!
+      minimum-space-to-comment=i
+      no-profile
+      nohtml-style-sheets
+      non-indenting-brace-prefix=s
+      non-indenting-braces!
+      noprofile
+      nospace-after-keyword=s
+      notidy
+      nowant-left-space=s
+      nowant-right-space=s
+      npro
+      one-line-block-nesting=i
+      one-line-block-semicolons=i
+      opening-anonymous-sub-brace-on-new-line!
+      opening-brace-always-on-right!
+      opening-brace-on-new-line!
+      opening-hash-brace-right!
+      opening-paren-right!
+      opening-square-bracket-right!
+      opening-sub-brace-on-new-line!
+      outdent-keyword-list=s
+      outdent-keywords!
+      outdent-labels!
+      outdent-long-comments!
+      outdent-long-quotes!
+      outdent-static-block-comments!
+      outfile=s
+      output-file-extension=s
+      output-line-ending=s
+      output-path=s
+      paren-tightness=i
+      paren-vertical-tightness-closing=i
+      paren-vertical-tightness=i
+      pass-version-line!
+      perl-syntax-check-flags=s
+      pod2html!
+      podflush
+      podheader!
+      podindex!
+      podpath=s
+      podquiet!
+      podrecurse!
+      podroot=s
+      podverbose!
+      preserve-line-endings!
+      profile=s
+      quiet!
+      recombine!
+      short-concatenation-item-length=i
+      show-options!
+      space-after-keyword=s
+      space-backslash-quote=i
+      space-for-semicolon!
+      space-function-paren!
+      space-keyword-paren!
+      space-prototype-paren=i
+      space-terminal-semicolon!
+      square-bracket-tightness=i
+      square-bracket-vertical-tightness-closing=i
+      square-bracket-vertical-tightness=i
+      stack-closing-block-brace!
+      stack-closing-hash-brace!
+      stack-closing-paren!
+      stack-closing-square-bracket!
+      stack-opening-block-brace!
+      stack-opening-hash-brace!
+      stack-opening-paren!
+      stack-opening-square-bracket!
+      standard-error-output!
+      standard-output!
+      starting-indentation-level=i
+      static-block-comment-prefix=s
+      static-block-comments!
+      static-side-comment-prefix=s
+      static-side-comments!
+      stylesheet
+      sub-alias-list=s
+      tabs!
+      tee-block-comments!
+      tee-pod!
+      tee-side-comments!
+      tight-secret-operators!
+      timestamp!
+      title=s
+      trim-pod!
+      trim-qw!
+      use-unicode-gcstring!
+      valign!
+      variable-maximum-line-length!
+      version
+      vertical-tightness-closing=i
+      vertical-tightness=i
+      want-break-after=s
+      want-break-before=s
+      want-left-space=s
+      want-right-space=s
+      warning-output!
+      weld-nested-containers!
+      whitespace-cycle=i
+    );
+
+    my %flag_types = (
+        '!'  => 'BINARY FLAG',
+        '=s' => 'STRING',
+        '=i' => 'INTEGER',
+        ':i' => 'OPTIONAL INTEGER',
+        ':s' => 'OPTIONAL STRING',
+    );
+
+    my @random_words = qw(bannanas sub train apples);
+    my @operators =
+      qw(% + - * / x != == >= <= =~ !~ < > | & = **= += *= &= <<= &&= -= /= |= >>= ||= //= .= %= ^= x=);
+    my @keywords = qw(my our local do while if  garbage1 34 );
+    my @colors   = qw(
+      ForestGreen
+      SaddleBrown
+      magenta4
+      IndianRed3
+      DeepSkyBlue4
+      MediumOrchid3
+      black
+      white
+      red
+
+      bubba
+    );
+
+    my %option_range = (
+        'format' => [ 'tidy', 'html' ],    #, 'user' ],
+        'output-line-ending' => [ 'dos', 'win', 'mac', 'unix' ],
+
+        'space-backslash-quote'         => [ 0, 2 ],
+        'block-brace-tightness'         => [ 0, 2 ],
+        'keyword-paren-inner-tightness' => [ 0, 2 ],
+        'brace-tightness'               => [ 0, 2 ],
+        'paren-tightness'               => [ 0, 2 ],
+        'square-bracket-tightness'      => [ 0, 2 ],
+
+        'block-brace-vertical-tightness'            => [ 0, 2 ],
+        'brace-vertical-tightness'                  => [ 0, 2 ],
+        'brace-vertical-tightness-closing'          => [ 0, 2 ],
+        'paren-vertical-tightness'                  => [ 0, 2 ],
+        'paren-vertical-tightness-closing'          => [ 0, 2 ],
+        'square-bracket-vertical-tightness'         => [ 0, 2 ],
+        'square-bracket-vertical-tightness-closing' => [ 0, 2 ],
+        'vertical-tightness'                        => [ 0, 2 ],
+        'vertical-tightness-closing'                => [ 0, 2 ],
+
+        'closing-brace-indentation'          => [ 0, 3 ],
+        'closing-paren-indentation'          => [ 0, 3 ],
+        'closing-square-bracket-indentation' => [ 0, 3 ],
+        'closing-token-indentation'          => [ 0, 3 ],
+
+        'closing-side-comment-else-flag' => [ 0, 2 ],
+        'comma-arrow-breakpoints'        => [ 0, 5 ],
+
+        'keyword-group-blanks-before' => [ 0, 2 ],
+        'keyword-group-blanks-after'  => [ 0, 2 ],
+
+        'space-prototype-paren' => [ 0, 2 ],
+
+        # Arbitrary limits to keep things readable
+        'blank-lines-after-opening-block'  => [ 0, 4 ],
+        'blank-lines-before-closing-block' => [ 0, 3 ],
+        'blank-lines-before-packages'      => [ 0, 3 ],
+        'blank-lines-before-subs'          => [ 0, 3 ],
+
+        'maximum-consecutive-blank-lines' => [ 0, 4 ],
+        'minimum-space-to-comment'        => [ 0, 10 ],
+
+        'indent-columns'           => [ 0, 10 ],
+        'continuation-indentation' => [ 0, 10 ],
+        'default-tabsize'          => [ 0, 8 ],
+        'entab-leading-whitespace' => [ 0, 8 ],
+
+        # TODO: FILL thESE with multiple random operators
+        'want-break-after'   => \@operators,    #['+', '-', '*', '=', '.'],
+        'want-break-before'  => \@operators,    #['+', '-', '*'],
+        'want-left-space'    => \@operators,    #['+', '-', '*'],
+        'want-right-space'   => \@operators,    #['+', '-', '*'],
+        'nowant-left-space'  => \@operators,    #['+', '-', '*'],
+        'nowant-right-space' => \@operators,    #['+', '-', '*'],
+
+        #'keyword-group-blanks-list=s
+        'keyword-group-blanks-size' => [ 0, 2, 4, 7, 10, 2.8, 1.8 ],
+
+        # TODO: FILL thESE with multiple random keywords
+        'space-after-keyword'   => \@keywords,
+        'nospace-after-keyword' => \@keywords,
+
+        'html-color-background'      => \@colors,
+        'html-color-bareword'        => \@colors,
+        'html-color-colon'           => \@colors,
+        'html-color-comma'           => \@colors,
+        'html-color-comment'         => \@colors,
+        'html-color-here-doc-target' => \@colors,
+        'html-color-here-doc-text'   => \@colors,
+        'html-color-identifier'      => \@colors,
+        'html-color-keyword'         => \@colors,
+        'html-color-label'           => \@colors,
+        'html-color-numeric'         => \@colors,
+        'html-color-paren'           => \@colors,
+        'html-color-pod-text'        => \@colors,
+        'html-color-punctuation'     => \@colors,
+        'html-color-quote'           => \@colors,
+        'html-color-semicolon'       => \@colors,
+        'html-color-structure'       => \@colors,
+        'html-color-subroutine'      => \@colors,
+        'html-color-v-string'        => \@colors,
+    );
+
+    my %is_multiword_list = (
+        'want-break-after'      => 1,
+        'want-break-before'     => 1,
+        'want-left-space'       => 1,
+        'want-right-space'      => 1,
+        'nowant-left-space'     => 1,
+        'nowant-right-space'    => 1,
+        'space-after-keyword'   => 1,
+        'nospace-after-keyword' => 1,
+    );
+
+    ###################################################################
+    # Some are best skipped, otherwise the program will just quit early
+    # Parameters can be added and removed from the list to customize
+    # testing.
+    # 'format' was added because html is not so interesting, but can be
+    # removed.
+    ###################################################################
+    my @q = qw(
+      DEBUG
+      quiet
+      logfile
+      logfile-gap
+      backup-and-modify-in-place
+      backup-file-extension
+      character-encoding
+      format-skipping-begin
+      format-skipping-end
+      outfile
+      output-file-extension
+      output-path
+      output-file-extension
+      output-line-ending
+      standard-output
+      standard-error-output
+      html
+      notidy
+      format
+      starting-indentation-level
+      tee-block-comments
+      tee-pod
+      tee-side-comments
+    );
+
+    my %skip;
+    @skip{@q} = (1) x scalar(@q);
+
+    foreach my $parameter (@parameters) {
+        my ( $name, $flag, $type ) = ( "", "", "" );
+        $parameter =~ s/\s+$//;
+        if ( $parameter =~ /^([\w\-]+)([^\s]*)/ ) {
+            $name = $1;
+            $flag = $2;
+            $flag = "" unless $flag;
+            $type = $flag_types{$flag} if ($flag);
+
+            next if $skip{$name};
+
+            # Skip all pattern lists
+            if ( $flag =~ /s$/ ) {
+                if (   $name =~ /-(list|prefix)/
+                    || $name =~ /character-encoding/ )
+                {
+                    next;
+                }
+            }
+
+            my $rrange = $option_range{$name};
+            ##print "$parameter => $name  $flag $type\n";
+            my $line = "";
+            if ( $flag eq '!' ) {
+                my $xx     = int( rand(1) + 0.5 );
+                my $prefix = $xx == 0 ? 'no' : "";
+                $line = "--$prefix$name";
+            }
+            elsif ( $flag eq '=s' ) {
+                my $string;
+                if ( !$rrange ) { $rrange = \@random_words }
+                my $imax  = @{$rrange} - 1;
+                my $count = 1;
+                if ( $is_multiword_list{$name} ) {
+                    $count = $imax / 2 + 1;
+                }
+                foreach my $i ( 1 .. $count ) {
+                    my $index = int( rand($imax) + 0.5 );
+                    if ( $i > 1 ) { $string .= ' ' }
+                    $string .= $rrange->[$index];
+                }
+                $string = "'$string'";
+                $line   = "--$name=$string";
+            }
+            elsif ( $flag eq '=i' ) {
+                my $int;
+                if ( !$rrange ) {
+                    $rrange = [ 0, 100 ];
+                }
+
+                # Two items are assumed to be a range
+                if ( @{$rrange} == 2 ) {
+                    my ( $imin, $imax ) = @{$rrange};
+                    my $frac = rand(1);
+                    $int = $imin + $frac * ( $imax - $imin );
+                    $int = int( $int + 0.5 );
+                }
+
+                # Otherwise, assume a list
+                else {
+                    my $ix    = @{$rrange} - 1;
+                    my $index = int( rand($ix) + 0.5 );
+                    $int = $rrange->[$index];
+                }
+                $line = "--$name=$int";
+            }
+            else {
+                my $xx = int( rand(1) + 0.5 );
+                next unless $xx;
+                $line = "--$name";
+            }
+
+            # Now randomly pick and omit flags
+            push @random_parameters, $line;
+        }
+    }
+    return \@random_parameters;
+}
+
+sub get_num {
+    my ( $msg, $default ) = @_;
+    if ( defined($default) ) {
+        $msg =~ s/:$//;
+        $msg .= " (<cr>=$default):";
+    }
+    my $ans = query($msg);
+    $ans = $default if ( defined($default) && $ans eq "" );
+    my $val = eval($ans);
+    if ($@) { warn $@; $val = $ans; }
+    return $val;
+}
+
+sub queryu {
+    return uc query(@_);
+}
+
+sub query {
+    my ($msg) = @_;
+    print $msg;
+    my $ans = <STDIN>;
+    chomp $ans;
+
+    #my $val=$ans;
+    return $ans;
+}