Click here to Skip to main content
15,896,557 members
Articles / Containers / Virtual Machine

TOOL

Rate me:
Please Sign up or sign in to vote.
4.98/5 (52 votes)
23 Oct 200676 min read 231.4K   5.4K   147  
TOOL (Tiny Object Oriented Language) is an easily-embedded, object-oriented, C++-like-language interpreter. The purpose of this article is to introduce the TOOL interpreter and language from the perspective of a person who has a desire to include a scripting solution as part of his project.
/*****************************************************************************/
/*                             SOURCE FILE                                   */
/*****************************************************************************/
/*
       $Archive: $

      $Revision: $
          $Date: $
        $Author: $

   Description: Class Implementation : CmdLineOptions 

                      TOOL And XML FORMS License
                      ==========================

                      Except where otherwise noted, all of the documentation 
                      and software included in the TOOL package is 
                      copyrighted by Michael Swartzendruber.

                      Copyright (C) 2005 Michael John Swartzendruber. 
                      All rights reserved.

                      Access to this code, whether intentional or accidental,
                      does NOT IMPLY any transfer of rights.

                      This software is provided "as-is," without any express 
                      or implied warranty. In no event shall the author be held
                      liable for any damages arising from the use of this software.

                      Permission is granted to anyone to use this software for 
                      any purpose, including commercial applications, and to 
                      alter and redistribute it, provided that the following 
                      conditions are met:

                      1. All redistributions of source code files must retain 
                         all copyright notices that are currently in place, 
                         and this list of conditions without modification.

                      2. The origin of this software must not be misrepresented;
                         you must not claim that you wrote the original software.

                      3. If you use this software in another product, an acknowledgment
                         in the product documentation would be appreciated but is
                         not required.

                      4. Modified versions in source or binary form must be plainly 
                         marked as such, and must not be misrepresented as being 
                         the original software.
*/
static char OBJECT_ID[] = "$Revision: $ : $Date: $";
/*****************************************************************************/


#pragma warning( disable : 4786 )      // turn off goofy little warnings about
#pragma warning( disable : 4503 )      // names too long from the stl


#include "../stdafx.h"  
#include <assert.h>
#include <iterator>
#include <string>
#include <map>
#include <vector>      
#include "CmdLineOptions.h"
#include "CmdLineException.h"



/*****************************************************************************/
/*
     FUNCTION NAME:  CmdLineOptions::CmdLineOptions

       DESCRIPTION:  ctor

             INPUT:  
           RETURNS:  
*/
CmdLineOptions::CmdLineOptions()
{
}
/*  end of function "CmdLineOptions::CmdLineOptions" */
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  CmdLineOptions::~CmdLineOptions

       DESCRIPTION:  dtor

             INPUT:  
           RETURNS:  
*/
CmdLineOptions::~CmdLineOptions()
{
  m_oCmdOptionsList.erase( m_oCmdOptionsList.begin(), m_oCmdOptionsList.end() );
  ResetMaps();
}
/*  end of function "CmdLineOptions::~CmdLineOptions" */
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  CmdLineOptions::ResetMaps

       DESCRIPTION:  Reset contents of all maps and lists. Called by destructor

             INPUT:  
           RETURNS:  
*/
void CmdLineOptions::ResetMaps( void )
{
  ENTRY_VALUES::iterator oEntry;

  for ( oEntry = m_oUserEntries.begin(); 
        oEntry != m_oUserEntries.end();
        oEntry++ )
  {
    CmdLineEntry* oContainer = (*oEntry).second;
    if ( CmdLineEntry::eList == oContainer->GetContainerType() )
      if ( !oContainer->m_oList.empty() )
        oContainer->m_oList.erase( oContainer->m_oList.begin(), 
                                  oContainer->m_oList.end() );
    else
      if ( !oContainer->m_oMap.empty() ) 
        oContainer->m_oMap.erase( oContainer->m_oMap.begin(), 
                                  oContainer->m_oMap.end() );
    delete oContainer;
  }
  m_oUserEntries.erase( m_oUserEntries.begin(), m_oUserEntries.end() );
  m_oAbbrMap.erase( m_oAbbrMap.begin(), m_oAbbrMap.end() );
}
/*  end of function "CmdLineOptions::ResetMaps" */
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  CmdLineOptions::Add

       DESCRIPTION:  Add the Option Description to the array. You need not  
                    worry about Option descriptions going out of scope because 
                    they are copied internally before being added to an option 
                    description array

             INPUT:  poOptionDescription : An Option Description
           RETURNS:  
*/
void CmdLineOptions::Add( CmdLineArg* poOptionDescription )
{
  bool bInserted = FALSE;
  
  for ( unsigned int i = 0; i < m_oCmdOptionsList.size(); i++ )		// 2b|!2b==?
  {
    std::string oArrayElement = m_oCmdOptionsList[ i ].GetOptName();
    std::string oNewElement   = poOptionDescription->GetOptName();

    // Insert with longest GetOptName's first
    //
    if ( oNewElement.length() >= oArrayElement.length() )
    {
      bInserted = TRUE;

      ARG_VECTOR::iterator oInsertPosition = m_oCmdOptionsList.begin();
      for ( unsigned int iLoop = 0; iLoop <= i; iLoop++ )		// 2b|!2b==?
        oInsertPosition++;

      m_oCmdOptionsList.insert( oInsertPosition, *poOptionDescription );
      break;
    }
  }
  if ( !bInserted )
    m_oCmdOptionsList.insert( m_oCmdOptionsList.end(), *poOptionDescription );
}
/*  end of function "CmdLineOptions::Add" */
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  CmdLineOptions::Add

       DESCRIPTION:  Add the Option Description to the array

             INPUT:  psczOptionName : the name of the option, CASE-INSENSITIVE
            iFlags : the flags of the option
            CMDLINE_ARGOK    Does option take an argument
            CMDLINE_REPEATOK  Is option valid more than once?
            CMDLINE_REP_FIRST  Use first if option is repeated
            CMDLINE_REP_LAST  Use last if option is repeated 
                                        (i.e. /l dir1 /l dir2)
            CMDLINE_REP_ARRAY  Build array if option is repeated
            CMDLINE_ASSOCIATIVE  Takes two arguments 
                                        i.e. /D variable=value or /D variable value
            CMDLINE_FIRSTARG  Takes an argument, is repeatable, 
                                        and repeats are ignored
            CMDLINE_LASTARG    Takes an argument, is repeatable, 
                                        and repeats are ignored
            CMDLINE_ARRAY    Takes an argument, is repeatable, builds an array
                    (i.e. The INCLUDE option would use this)
            CMDLINE_ASSOCARRAY  Takes two arguments, is repeatable, builds 
                                        associative array  
                    
         psczDescription : the description of the option, for usage messages
         psczAbbr : the abbreviation of the option.
              A DEFINITE abbreviation of the argument, this abbreviation will
              be used unless it conflicts with another option's DEFINITE 
                            abbreviation.
              This can be used to have an abbreviation of I for the INCLUDE 
                            option, even if there is another option which begins with I.
              For all options, any UNIQUE shortening of the option name is 
                            acceptable.
              For example, with an option name of INCLUDE, possible 
                            abbreviations would be I, IN, INC, INCL, INCLU, INCLUD.  
                            Which of these possibilities are valid, depends on which ones 
                            are are unique for a given option set. 
                            The DEFINITE abbreviation need not be a true abbreviation of 
                            the option name.
              For example, an option name EXPORT, could have a DEFINITE 
                            abbreviation of X even though that is not strictly an 
                            abbreviation of the name.
           RETURNS:  
*/
void CmdLineOptions::Add( const char* pszcOptionName, 
                          const int   iFlags,
                          const char* pszcDescription, 
                          const char* pszcAbbr )
{
  CmdLineArg oToAdd( pszcOptionName, iFlags, pszcDescription, pszcAbbr );
  Add( &oToAdd );
}
/*  end of function "CmdLineOptions::Add" */
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  CmdLineOptions::Remove

       DESCRIPTION:  Removes this option from all internal lists

             INPUT:  
           RETURNS:  TRUE is item found/removed FALSE otherwise
*/
bool CmdLineOptions::Remove( const char* pszcOption )
{
  std::string oOption = pszcOption;
  for ( std::string::iterator iter = oOption.begin(); 
        iter != oOption.end();
        iter++ )
    (*iter) = toupper( *iter );

  ENTRY_VALUES::iterator oDeleteLocation = m_oUserEntries.find( oOption );  
  if ( oDeleteLocation != m_oUserEntries.end() )
  {
    CmdLineEntry* oContainer = (*oDeleteLocation).second;
    if ( CmdLineEntry::eList == oContainer->GetContainerType() )
      if ( !oContainer->m_oList.empty() )
        oContainer->m_oList.erase( oContainer->m_oList.begin(), 
                                   oContainer->m_oList.end() );
    else
      if ( !oContainer->m_oMap.empty() ) 
        oContainer->m_oMap.erase( oContainer->m_oMap.begin(), 
                                  oContainer->m_oMap.end() );
    delete oContainer;
    m_oUserEntries.erase( oDeleteLocation );
  }
  ABBR_MAP::iterator oDelLocation = m_oAbbrMap.find( oOption );
  if ( oDelLocation != m_oAbbrMap.end() )
    m_oAbbrMap.erase( oDelLocation );

  bool bFound = FALSE;

  for ( unsigned int i = 0; i < m_oCmdOptionsList.size(); i++ )		// 2b|!2b==?
  {
    CmdLineArg oArg = m_oCmdOptionsList[ i ];
    if ( oArg.GetOptName() == oOption )
    {
      ARG_VECTOR::iterator oDeleteLocation = m_oCmdOptionsList.begin();
      for ( unsigned int k = 0; k <= i; k++ )		// 2b|!2b==?
        oDeleteLocation++;

      m_oCmdOptionsList.erase( oDeleteLocation );

      bFound = TRUE;
      break;
    }
  }
  return bFound;
}
/*  end of function "CmdLineOptions::Remove" */
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  CmdLineOptions::BuildAbbrTable

       DESCRIPTION:  walk through CmdOptDescList, gathering .GetOptName() 
                    abbreviations. Use this info to construct an abbreviation
                    map

             INPUT:  
           RETURNS:  
*/
void CmdLineOptions::BuildAbbrTable( void )
{
  STRING_ARRAY   oAbbrevArray;
  std::vector<unsigned int>  oIndexArray;
  STRING_ARRAY   oClashArray;

  // Initialize oAbbrevArray with complete option names 
  // (and oIndexArray with pointers). This array is size 
  // sorted because CmdOptDescList is size sorted
  //
  for ( unsigned int i = 0; i < m_oCmdOptionsList.size(); i++ )
  {
    oAbbrevArray.insert( oAbbrevArray.end(), m_oCmdOptionsList[i].GetOptName() );
    oIndexArray.insert( oIndexArray.end(), i );

    std::string oReqAbbr = m_oCmdOptionsList[i].GetOptAbbr();

    if ( oReqAbbr.length() )
    {
      oAbbrevArray.insert( oAbbrevArray.end(), oReqAbbr );
      oIndexArray.insert( oIndexArray.end(),  i );
    }
  }
  
  // Now walk through AbbrMap extending it as we go with abbreviations
  //
  unsigned int iAbbr;		// 2b|!2b==?

  for ( iAbbr = 0;iAbbr < oAbbrevArray.size(); iAbbr++ )
  {
    std::string sAbbr = oAbbrevArray[ iAbbr ];

    // Abbr is the name already in the map
    //
    int iNewAbbrLength = sAbbr.length() - 1;

    if ( iNewAbbrLength )
    {  
      // No zero length abbreviations
      // NewAbbr is the name we are trying to add to map
      //
      std::string sNewAbbr = sAbbr.substr( 0, iNewAbbrLength );

      // See if sNewAbbr is unique 
      // (ignoring all the entries we've already processed)
      //
      bool bUnique = TRUE;
      
      unsigned int iCmp;		// 2b|!2b==?

      for ( iCmp = iAbbr + 1; iCmp < oAbbrevArray.size(); iCmp++ )
      {
        // Is sNewAbbr an abbreviation of sCmp?
        // Assumes that Left() returns all characters (without
        // complaint) in the case that Left() is passed a number
        // larger than the string length.
        //
        std::string sCmp = oAbbrevArray[ iCmp ].substr( 0, sNewAbbr.length() );
        
        if ( sCmp == sNewAbbr )
        {
          // sNewAbbr is not unique ... abandon it
          //
          bUnique = FALSE;
          break;
        }
      }

      // Did we previously find a clash that's a substring of sNewAbbr
      //
      if ( bUnique )
      {
        for ( unsigned int iClash = 0; iClash < oClashArray.size(); iClash++ )		// 2b|!2b==?
        {
          std::string sCmp = oClashArray[ iClash ];
          if ( sCmp == sNewAbbr )
          {
            bUnique = FALSE;
            break;
          }
        }
      }

      if ( bUnique )
      {
        oAbbrevArray.insert( oAbbrevArray.end(), sNewAbbr );
        oIndexArray.insert( oIndexArray.end(), oIndexArray[ iAbbr ] );
      }
      else
      {
        oClashArray.insert( oClashArray.end(), sNewAbbr );
      }
    }
  }  
  assert( oAbbrevArray.size() == oIndexArray.size() );
  
  // Hmmm, this will freak if user calls this twice ... handle that case -tab
  //
  assert( m_oAbbrMap.size() == 0 );
  
  // Now Build AbbrMap from oAbbrevArray and oIndexArray
  //
  for ( unsigned int j = 0; j < oAbbrevArray.size(); j++ )	// 2b|!2b==?
  {
    std::string  oKey   = oAbbrevArray[ j ];
    unsigned int iIndex = oIndexArray[ j ];
    CmdLineArg  oArg    = m_oCmdOptionsList[ iIndex  ];

    m_oAbbrMap.insert( ABBR_MAP::value_type( oKey, oArg ) );
  }
}
/*  end of function "CmdLineOptions::BuildAbbrTable" */
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  CmdLineOptions::ParseCmdLine

       DESCRIPTION:  Construct array of actual parameters based on command 
                    line object. Can throw an CCommandLineException

             INPUT:   oCmdLine : the Command line object to parse
                     pRestList : when provided will contain the strings on the 
                             command line that aren't flags. Is actually 
                             the same as the return string except that the 
                             separate parts are stored in a Stringlist.

           RETURNS: Anything left over on the command line after parsing 
                    the valid options  
*/
std::string CmdLineOptions::ParseCmdLine( CmdLine& oCmdLine, 
                                          STRING_ARRAY* pRestList )
{
  std::string oReturn;
  
  // Clear all previous maps and rebuild afterwards
  //
  ResetMaps();
  BuildAbbrTable();

  int iNumArgs = oCmdLine.GetNumArgs();

  for ( int iArg = 0; iArg <= iNumArgs; iArg++ )
  {
    std::string oToken = oCmdLine[ iArg ];
    if ( ( '-' == oToken[ 0 ] ) || ( '/' == oToken[ 0 ] ) )
      oToken = oToken.substr( 1, oToken.length() );

    for ( std::string::iterator iter = oToken.begin(); 
          iter != oToken.end();
          iter++ )
      (*iter) = toupper( *iter );

    ABBR_MAP::iterator oMapLocation = m_oAbbrMap.find( oToken );

    if ( oMapLocation != m_oAbbrMap.end() )
    {  
      // Valid switch or abbreviation
      //
      CmdLineArg oTemp = m_oAbbrMap[ oToken ];

      ENTRY_VALUES::iterator oLocation = m_oUserEntries.find( oTemp.GetOptName() );
      bool bIsAlreadyThere;
  
      if (  oLocation != m_oUserEntries.end() )
         bIsAlreadyThere = true;
      else
         bIsAlreadyThere = false;
        
      if ( bIsAlreadyThere && ( !oTemp.IsRepeatable() ) )
      {
        char achMsg[ 80 ];
        sprintf( achMsg, 
                 "%s can only be specified once\r\n", 
                 oToken.c_str() );
        throw( new CmdLineException( achMsg, this ) );
      }
      else 
      if ( bIsAlreadyThere && oTemp.ReturnsFirstRep() )
      {
        // It's already there ... do nothing
      }
      else
      {
        // no entry found for this argument yet, so make a new container
        // for this argument
        //
        if ( !bIsAlreadyThere )
        {
          if ( oTemp.ReturnsAssociative() )
            m_oUserEntries.insert( ENTRY_VALUES::value_type( oTemp.GetOptName(), 
                                                             new CmdLineEntry( CmdLineEntry::eMap ) ) );
          else
            m_oUserEntries.insert( ENTRY_VALUES::value_type( oTemp.GetOptName(), 
                                                             new CmdLineEntry( CmdLineEntry::eList ) ) );
        }

        if ( oTemp.TakesArg() && !oTemp.ReturnsArray() && !oTemp.ReturnsAssociative() )
        {
           // grab the next command line argument and stash it into to the list
           // with the current key
           //
           ENTRY_VALUES::iterator oLocation = m_oUserEntries.find( oTemp.GetOptName() );
           CmdLineEntry* oContainer = (*oLocation).second;
           assert( oContainer->GetContainerType() == CmdLineEntry::eList );    

           if ( !oContainer->m_oList.empty() )       
             oContainer->m_oList.erase( oContainer->m_oList.begin(), 
                                        oContainer->m_oList.end() );

           oContainer->m_oList.insert( oContainer->m_oList.end(), oCmdLine[ ++iArg ] );
        }
        else 
        if ( oTemp.ReturnsAssociative() )
        {
          if ( iArg + 2 > iNumArgs  )
          {
             char achMsg[80];
             sprintf( achMsg, 
                      "%s requires 2 arguments\r\n", 
                      oTemp.GetOptName() );
             throw( new CmdLineException( achMsg, this ) );
          }
          ENTRY_VALUES::iterator oLocation = m_oUserEntries.find( oTemp.GetOptName() );

          if ( oLocation == m_oUserEntries.end() )
          {
            m_oUserEntries.insert( ENTRY_VALUES::value_type( oTemp.GetOptName(), 
                                                             new CmdLineEntry( CmdLineEntry::eMap ) ) );
          }
          assert( (*oLocation).second->GetContainerType() == CmdLineEntry::eMap );
          (*oLocation).second->m_oMap.insert( STRING_MAP_TO_STRING::value_type( oCmdLine[ ++iArg ], 
                                                                                oCmdLine[ ++iArg ] ) );
        }
        else 
        if ( oTemp.ReturnsArray() )
        {
          // in this case, either create a key/value pair --or--
          // append the new argument on to the existing key value 
          // pair
          //
          if ( iArg + 1 > iNumArgs /*-1*/ )
          {
            char achMsg[ 80 ];
            sprintf( achMsg, 
                     "%s requires argument\r\n", 
                     oTemp.GetOptName() );
            throw( new CmdLineException( achMsg, this ) );
          }
          ENTRY_VALUES::iterator oLocation = m_oUserEntries.find( oTemp.GetOptName() );
          CmdLineEntry*  oContainer = (*oLocation).second;
          assert( oContainer->GetContainerType() == CmdLineEntry::eList );

          oContainer->m_oList.insert( oContainer->m_oList.end(), oCmdLine[ ++iArg] );
        }
      }    
    }
    else
    {
      if ( pRestList != NULL )
      {
        pRestList->insert( pRestList->end(), oCmdLine[ iArg ] );
      }
      oReturn += oCmdLine[ iArg ]; 
      oReturn += " ";
    }
  }

  // Glue the remaining strings back together
  //
  while ( iArg < oCmdLine.GetNumArgs() )
  {
    oReturn += oCmdLine[ iArg++ ];
    oReturn += " ";
  }
  return oReturn;
}
/*  end of function "CmdLineOptions::ParseCmdLine" */
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  CmdLineOptions::GetOptionObject

       DESCRIPTION:  Finds/returns the Option descriptor for the given command
                    line option

             INPUT:  psczOption : the name of the option
           RETURNS:  the option object with pszcOption as NAME.  NULL if not found.
*/
const CmdLineArg* CmdLineOptions::GetOptionObject( const char* psczOption ) const
{
  std::string oOption( psczOption );
  for ( std::string::iterator iter = oOption.begin(); 
        iter != oOption.end();
        iter++ )
    (*iter) = toupper( *iter );

  bool bFound( FALSE );
  CmdLineArg oArg;

  for ( unsigned int i = 0; i < m_oCmdOptionsList.size(); i++ )		// 2b|!2b==?
  {
    oArg = m_oCmdOptionsList[ i ];
    if ( oArg.GetOptName() == oOption )
    {
      bFound = TRUE;
      break;
    }
  }  
  return bFound ? &oArg : NULL;
}
/*  end of function "CmdLineOptions::GetOptionObject" */
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  CmdLineOptions::IsEnabled

       DESCRIPTION:  works for any of the argument forms. Determines whether
                    or not the command line option was entered.

             INPUT:  pszcOption : the option to look for
           RETURNS:  Did the option appear on the command line or not
*/
bool CmdLineOptions::IsEnabled( const char* pszcOption ) const
{
  std::string oOption = pszcOption;
  for ( std::string::iterator iter = oOption.begin(); 
        iter != oOption.end();
        iter++ )
    (*iter) = toupper( *iter );

  return ( m_oUserEntries.end() != m_oUserEntries.find( oOption ) );
}
/*  end of function "CmdLineOptions::IsEnabled" */
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  CmdLineOptions::GetValue

       DESCRIPTION:  Can be used with single-occurrence, single-argument options

             INPUT:  pszcOption: the option to look up the values for 
           RETURNS:  The argument associated with the option
*/
std::string CmdLineOptions::GetValue( const char* pszcOption ) const
{
  std::string oOption = pszcOption;
  for ( std::string::iterator iter = oOption.begin(); 
        iter != oOption.end();
        iter++ )
    (*iter) = toupper( *iter );

  CmdLineArg oArgument;

  ABBR_MAP::const_iterator oMapLocation = m_oAbbrMap.find( oOption );

  if ( m_oAbbrMap.end() != oMapLocation )
  {
    oArgument = (*oMapLocation).second;

    assert( !oArgument.ReturnsArray() && !oArgument.ReturnsAssociative() );

    ENTRY_VALUES::const_iterator oEntries = m_oUserEntries.find( oOption );
    if ( m_oUserEntries.end() != oEntries )
    {
      CmdLineEntry* oContainer = (*oEntries).second;
      assert( oContainer->GetContainerType() == CmdLineEntry::eList );
      return( oContainer->m_oList[0] );
    }
    else
      return "";
  }
  else
    return "";
}
/*  end of function "CmdLineOptions::GetValue" */
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  CmdLineOptions::GetValues

       DESCRIPTION:  Can be used with single-argument, multiple-occurrence 
                    options

             INPUT: pszcOption: the name of the option to get the values for  
           RETURNS:  The list of arguments associated with the option
*/
const STRING_ARRAY* CmdLineOptions::GetValues( const char* pszcOption ) const
{
  std::string oOption = pszcOption;
  for ( std::string::iterator iter = oOption.begin(); 
        iter != oOption.end();
        iter++ )
    (*iter) = toupper( *iter );

  CmdLineArg oArgument;

  ABBR_MAP::const_iterator oMapLocation = m_oAbbrMap.find( oOption );

  if ( m_oAbbrMap.end() != oMapLocation )
  {
    oArgument = (*oMapLocation).second;

    assert( oArgument.ReturnsArray() );

    ENTRY_VALUES::const_iterator oEntries = m_oUserEntries.find( oOption );
    if ( m_oUserEntries.end() != oEntries )
    {
      CmdLineEntry* oContainer = (*oEntries).second;
      assert( oContainer->GetContainerType() == CmdLineEntry::eList );
      return( &( oContainer->m_oList ) );
    }
    else
      return NULL;
  }
  else
    return NULL;
}
/*  end of function "CmdLineOptions::GetValues" */
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  CmdLineOptions::GetAssocPairs

       DESCRIPTION:  Is used with options that take two arguments, the first 
                    being a key name, the second the value of of the key.  This 
                    is useful for options that set variables like 
                    -Dfoo=bar

             INPUT:  pszcOption: the argument to get the values for
           RETURNS:  The list of combined arguments associated with the option
*/
const STRING_MAP_TO_STRING* CmdLineOptions::GetAssocPairs( const char* pszcOption ) const
{
  std::string oOption = pszcOption;
  for ( std::string::iterator iter = oOption.begin(); 
        iter != oOption.end();
        iter++ )
    (*iter) = toupper( *iter );

  CmdLineArg oArgument;

  ABBR_MAP::const_iterator oMapLocation = m_oAbbrMap.find( oOption );

  if ( m_oAbbrMap.end() != oMapLocation )
  {
    oArgument = (*oMapLocation).second;
 
    assert( oArgument.ReturnsAssociative() );

    ENTRY_VALUES::const_iterator oEntries = m_oUserEntries.find( oOption );
    if ( m_oUserEntries.end() != oEntries )
    {
      CmdLineEntry* oContainer = (*oEntries).second;
      assert( oContainer->GetContainerType() == CmdLineEntry::eMap );
      return( &( oContainer->m_oMap ) );
    }
    else
    {
      return NULL;
    }
  }
  else
    return NULL;
}
/*  end of function "CmdLineOptions::GetAssocPairs" */
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  CmdLineOptions::Usage

       DESCRIPTION:  prints usage message if StdHandles are available

             INPUT:  
           RETURNS:  
*/
std::string CmdLineOptions::Usage( const char* pszcMsg ) const
{
  std::string oMsg( pszcMsg );
  std::string oLine;
  
  oMsg += "\n";
  
  for ( unsigned int i = 0; i < m_oCmdOptionsList.size(); i++ )		// 2b|!2b==?
  {
    CmdLineArg oArgument = m_oCmdOptionsList[ i ];
    std::string oAbbr = oArgument.GetOptAbbr();

    if ( oAbbr.length() )
    {
      std::string oTemp = "(-";
      oTemp += oAbbr;
      oTemp += ")";
      oAbbr = oTemp;
    }

    oLine  = oArgument.GetOptName();
    oLine += "\t";
    oLine += oAbbr;
    oLine += "\t";
    oLine += oArgument.GetDescription();
    oLine += "\n";

    oMsg += oLine;
  }
  return oMsg; 
}
/*  end of function "CmdLineOptions::Usage" */
/*****************************************************************************/



/*****************************************************************************/
/* Check-in history */
/*
*$Log: $
*/
/*****************************************************************************/
    



By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions