# ---------------------------------------------------------------------------
# 
# File:    HELP.pm
#
# Copyright (c) Programming Research, 2004.
#
# Written: C.Waddingham 20-Aug-04
#
# Version: 1.1
#
# Purpose: To provide help capability for qaw.pl.
#
# History: 
#   Date      Version By   Comment
#   --------  ------- ---- ----------------------------------------------
#   24-10-06  1.1     CW   Updated list of QAW options help.
#
# ---------------------------------------------------------------------------

package HELP; #==============================================================

require Exporter;
our @ISA = qw( Exporter );

use strict;

require OPC;
require PARAM;

#----------------------------------------------------------------------------

BEGIN
{
}

#----------------------------------------------------------------------------

sub DISPLAY_HELP
{
   # Usage: DISPLAY_HELP( $cfg_filename, $ar_options );
   #
   my $cfg_filename = shift;
   my $ar_options   = shift;

   my @help_section = LOAD_CFG_HELP_SECTION( $cfg_filename );
   my %help         = GET_CFG_HELP( \@help_section );
   my $qa_program   = PARAM::QA_PROGRAM();
   
   if ( $qa_program eq "QAC" )
   {
      if ( ( scalar( @$ar_options ) == 1 ) && 
           ( lc( $$ar_options[ 0 ] ) =~ /^-(h|help)$/oi )
         )
      {
   	 # Display all help
   	 #
   	 foreach my $key ( sort keys %help )
   	 {
            OPC::PUT_MSG_LINE( "" );
            OPC::PUT_MSG_LINE( $key );
            OPC::PUT_MSG_LINE( $help{ $key } );
   	 }
      }
      else
      {
   	 # Display selected help
   	 #
 
         # Strip first option as this is -h or -help
         #
         my ( $ignore, @help_query ) = @$ar_options;
 
   	 foreach my $opt ( @help_query )
   	 {
   	    KEY:
   	    foreach my $key ( sort keys %help )
   	    {
   	       # Get first word of $key
   	       #
   	       my ( $kwd, $ignored ) = split( " ", lc( $key ) );
   
   	       $opt = lc( $opt );
   
   	       # Ensure first 2 chars of $kwd are same as those of $opt
   	       #
   	       next KEY if ( substr( $kwd, 0, 2 ) ne substr( $opt, 0, 2 ) );
   
   	       # Match remaining chars of $opt with $kwd, allowing gaps
   	       # but must be in order
   	       #
   	       my $ich = 2;
   	       foreach my $ch ( split( //o, substr( $opt, 2 ) ) )
   	       {
   		  $ich = index( $kwd, $ch, $ich );
   		  next KEY if ( $ich == -1 );
   	       }
   	       
               OPC::PUT_MSG_LINE( "" );
               OPC::PUT_MSG_LINE( $key );
               OPC::PUT_MSG_LINE( $help{ $key } );
   	    }
   	 }
      }
   }
   else
   {
      # Here when handling -help for QAC++
      # Note that #help section of qacpp.cfg is completely different
      # to that of qac.cfg.  Hence display all of #help section and
      # the qaw specific help.
      #

      foreach my $line ( @help_section )
      { 
         chomp $line;
         OPC::PUT_MSG_LINE( "    " . $line );
      }
     
      my %qaw_option_help = GET_QAW_OPTION_HELP();

      foreach my $key ( sort keys %qaw_option_help )
      {
         OPC::PUT_MSG_LINE( "" );
         OPC::PUT_MSG_LINE( $key );
         OPC::PUT_MSG_LINE( $qaw_option_help{ $key } );
      }
   }
}

# ---------------------------------------------------------------------------

sub LOAD_CFG_HELP_SECTION
{
   # Usage %help = LOAD_CFG_HELP_SECTION( $cfg_filename );
   #
   my $cfg_filename = shift;

   my @help_section = ();

   open CFG_FILE, "<$cfg_filename" or GEN::DIE( ": Cannot open \"$cfg_filename\"\n$!" );

   # Skip to #help line
   #
   my $line = <CFG_FILE>;

   while ( ! eof( CFG_FILE ) && ( $line !~ /^#help\s*$/o ) )
   {
      $line = <CFG_FILE>;
   }

   # Skip the line containing #help
   #
   if ( ! eof( CFG_FILE ) )
   {
      $line = <CFG_FILE>;
   }

   # Read help part of cfg file
   #
   HELP_TOPIC:
   while ( ! eof( CFG_FILE ) && ( substr( $line, 0, 1 ) ne "*" ) )
   {
      push @help_section, $line;

      $line = <CFG_FILE>;
   }

   close CFG_FILE;

   return @help_section;
}

# ---------------------------------------------------------------------------

sub GET_QAW_OPTION_HELP
{
   # Usage: @qaw_option_help = GET_QAW_OPTION_HELP();
   #
   my %qaw_option_help = ();

   $qaw_option_help{ '-afe' } = "    Specify analysis filename extensions.
    -afe \"<period separated list of extensions>\"

    e.g. -afe \".c.h.c++.any*\"";

   $qaw_option_help{ '-dafe' } = "    Specify display of analysis filename errors.
    -dafe+|-

    When set to -dafe-, this option results in unrecognised
    analysis file name warnings being suppressed.";

   $qaw_option_help{ '-disp' } = "    Display annotated source for analysis.";

   $qaw_option_help{ '-ehtml' } = "    Ensure .html files are current.";

   $qaw_option_help{ '-etxt' } = "    Ensure .txt files are current.";

   $qaw_option_help{ '-exec' } = "    Execute Post-Analysis.
    -exec \"<program>#<script>#<parameters>\"

    e.g. -exec \"qacuser##%F\"";

   $qaw_option_help{ '-fdisp' } = "    Write annotated source for analysis to file.
    -fdisp <filename>.";

   $qaw_option_help{ '-glob' } = "    Perform Global Analysis.
    -glob \"<program>#<parameters [-file <name>][-file STDOUT]>[#<renderer program>]\"

    e.g. -glob \"mcmprj#-list %l -file %r -html %p#iexplore\"
    n.b. If not supplied, renderer program defaults to Env Var: " . PARAM::PRQA_DEFAULT_BROWSER_PARAM_NAME();

   $qaw_option_help{ '-pdsp' } = "    Invoke Warning Listing Viewer.
    -pdsp [ \"<renderer program>\" ]

    e.g. -pdsp \"iexplore\"";

   $qaw_option_help{ '-pdspd' } = "    Invoke Warning Listing Viewer using default browser.
    -pdspd

    e.g. -pdspd";

   $qaw_option_help{ '-plog' } = "    Log of analysis status to standard output.";

   $qaw_option_help{ '-maseq' } = "    Specify programs for project wide analysis sequence.
    -maseq <argument>

    Where argument = program_spec { # program_spec } 
    And program_spec = program_path ' ' parameters

    e.g. -maseq \"mcmprj -list \%L -html \%R+ \%P+#pal \%Q \%L+ \%P+\"";
    
   $qaw_option_help{ '-saseq' } = "    Specify programs for single file analysis sequence.
    -saseq <argument>

    Where argument = program_spec { # program_spec } 
    And program_spec = program_path ' ' parameters

    e.g. -saseq \"C:\\Program\\ Files\\prqa\\QAC-5.0-P3\\mcm\\bin\\qacuser_mcm.exe \%F\"";

   $qaw_option_help{ '-mode' } = "    Control analysis of files.
    -mode all | depend | none

    e.g. -mode depend

    -mode depend results in only those files that have been
    modified, or their anaylsis parameters modified, being
    analysed, or .err / .met / .opt file(s) don't exist.";

   $qaw_option_help{ '-alias' } = "    Set local variable.
    -alias \"<name>=<expansion>\"

    e.g. -alias \"QAC=\\Program Files\\PRQA\\QAC-6.0\"";

   $qaw_option_help{ '-canal' } = "    Run configured analysis program.
    -canal <analysis program full name> 

    e.g. -canal pal.exe";

   $qaw_option_help{ '-crep' } = "    Run configured report program.
    -crep <name of configured report> 

    e.g. -crep \"Code Review\"";

   $qaw_option_help{ '-version' } = "    Request QAW version.
    -version | -ver | -v";

   $qaw_option_help{ '-sapf' } = "    Invoke display of analysis parameters.";

   $qaw_option_help{ '-sfba' } = "    Suppress file based analysis.";

   $qaw_option_help{ '-view' } = "    Invoke Viewer on analysis completion.";

   $qaw_option_help{ '-trace' } = "    Write " . lc( PARAM::EXECUTABLE_NAME() ) . ".trace";

   $qaw_option_help{ '-cargs' } = "    Marks start of compiler parameters.";

   $qaw_option_help{ '-targs' } = "    Marks start of translation parameters.";

   $qaw_option_help{ '-sat' } = "    Set Argument Translation.
    -sat \"<compiler option>=<replacement qac[pp] option>\"

    e.g. -sat \"i=-I\"";

   $qaw_option_help{ '-logmsgs' } = "    Sets direction of " . 
    PARAM::EXECUTABLE_NAME() . " output.
    -logmsgs [ 'STDOUT' ][ 'STDERR' ][ 'FILE' ]

    e.g. -logmsgs FILE

    - causes " . PARAM::EXECUTABLE_NAME() . " output to be directed to " .
    lc( PARAM::EXECUTABLE_NAME() ) . "_msg.log";

   $qaw_option_help{ '-logerrs' } = "    Sets direction of " . 
    PARAM::EXECUTABLE_NAME() . " output.
    -logerrs [ 'STDOUT' ][ 'STDERR' ][ 'FILE' ]

    e.g. -logerrs FILE

    - causes " . PARAM::EXECUTABLE_NAME() . " output to be directed to: " .
    lc( PARAM::EXECUTABLE_NAME() ) . "_err.log";

   $qaw_option_help{ '-stoponfail' } = "    Causes execution of " .
     PARAM::EXECUTABLE_NAME() . " to terminate on analysis error.";

   return %qaw_option_help;
}
   
# ---------------------------------------------------------------------------

sub GET_CFG_HELP
{
   # Usage %help = GET_CFG_HELP( $ar_help_section );
   #
   my $ar_help_section = shift;

   my %help = ();

   # Read help section
   #
   my $i_line = 0;

   HELP_LINE:
   while ( $i_line <= $#$ar_help_section )
   {
      my $line = $$ar_help_section[ $i_line ];

      # Skip any leading blank lines to get to option title
      #
      while ( $line =~ /^\s*$/o )
      {
         ++$i_line;
         next HELP_LINE;
      }

      # Get the title
      #
      chomp $line;
      my $title = $line;

      # Read the help text
      #
      ++$i_line;
      last HELP_LINE if ( $i_line > $#$ar_help_section );

      my $text = "";
      $line    = $$ar_help_section[ $i_line ];

      HELP_TOPIC:
      while ( ( $i_line <= $#$ar_help_section ) &&
              ( substr( $line, 0, 1 ) !~ /[-\*]/o )
            )
      {
         ( $line = $line ) =~ s/^[ \t]*//o;

         $text .= "    " . $line;

         ++$i_line;
         last HELP_TOPIC if ( $i_line > $#$ar_help_section );

         $line = $$ar_help_section[ $i_line ];

         last HELP_TOPIC if ( substr( $line, 0, 1 ) eq "*" );
      }

      # Trim trailing eols and save
      #
      ( $help{ $title } = $text ) =~ s/\s*$//o;
   }

   # Append help for qaw options
   #
   my %qaw_option_help = GET_QAW_OPTION_HELP();

   foreach my $key ( keys %qaw_option_help )
   {
      $help{ $key } = $qaw_option_help{ $key };
   }

   return %help;
}

# -- eof HELP.pm ------------------------------------------------------------
