--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: wx/cmdline.h
+// Purpose: wxCmdLineParser and related classes for parsing the command
+// line options
+// Author: Vadim Zeitlin
+// Modified by:
+// Created: 04.01.00
+// RCS-ID: $Id$
+// Copyright: (c) 2000 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence: wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_CMDLINE_H_
+#define _WX_CMDLINE_H_
+
+#ifdef __GNUG__
+ #pragma interface "cmdline.h"
+#endif
+
+#include "wx/string.h"
+
+class WXDLLEXPORT wxDateTime;
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// by default, options are optional (sic) and each call to AddParam() allows
+// one more parameter - this may be changed by giving non-default flags to it
+enum
+{
+ wxCMD_LINE_OPTION_MANDATORY = 0x01, // this option must be given
+ wxCMD_LINE_PARAM_OPTIONAL = 0x02, // the parameter may be omitted
+ wxCMD_LINE_PARAM_MULTIPLE = 0x04, // the parameter may be repeated
+ wxCMD_LINE_OPTION_HELP = 0x08 // this option is a help request
+};
+
+// an option value or parameter may be a string (the most common case), a
+// number or a date
+enum wxCmdLineParamType
+{
+ wxCMD_LINE_VAL_STRING, // should be 0 (default)
+ wxCMD_LINE_VAL_NUMBER,
+ wxCMD_LINE_VAL_DATE,
+ wxCMD_LINE_VAL_NONE
+};
+
+// for constructing the cmd line description using Init()
+enum wxCmdLineEntryType
+{
+ wxCMD_LINE_SWITCH,
+ wxCMD_LINE_OPTION,
+ wxCMD_LINE_PARAM,
+ wxCMD_LINE_NONE // to terminate the list
+};
+
+// ----------------------------------------------------------------------------
+// wxCmdLineEntryDesc is a description of one command line
+// switch/option/parameter
+// ----------------------------------------------------------------------------
+
+struct wxCmdLineEntryDesc
+{
+ wxCmdLineEntryType kind;
+ const wxChar *shortName;
+ const wxChar *longName;
+ const wxChar *description;
+ wxCmdLineParamType type;
+ int flags;
+};
+
+// ----------------------------------------------------------------------------
+// wxCmdLineParser is a class for parsing command line.
+//
+// It has the following features:
+//
+// 1. distinguishes options, switches and parameters; allows option grouping
+// 2. allows both short and long options
+// 3. automatically generates the usage message from the cmd line description
+// 4. does type checks on the options values (number, date, ...)
+//
+// To use it you should:
+//
+// 1. construct it giving it the cmd line to parse and optionally its desc
+// 2. construct the cmd line description using AddXXX() if not done in (1)
+// 3. call Parse()
+// 4. use GetXXX() to retrieve the parsed info
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxCmdLineParser
+{
+public:
+ // ctors and initializers
+ // ----------------------
+
+ // default ctor or ctor giving the cmd line in either Unix or Win form
+ wxCmdLineParser() { Init(); }
+ wxCmdLineParser(int argc, char **argv) { Init(); SetCmdLine(argc, argv); }
+ wxCmdLineParser(const wxString& cmdline) { Init(); SetCmdLine(cmdline); }
+
+ // the same as above, but also gives the cmd line description - otherwise,
+ // use AddXXX() later
+ wxCmdLineParser(const wxCmdLineEntryDesc *desc)
+ { Init(); SetDesc(desc); }
+ wxCmdLineParser(const wxCmdLineEntryDesc *desc, int argc, char **argv)
+ { Init(); SetCmdLine(argc, argv); SetDesc(desc); }
+ wxCmdLineParser(const wxCmdLineEntryDesc *desc, const wxString& cmdline)
+ { Init(); SetCmdLine(cmdline); SetDesc(desc); }
+
+ // set cmd line to parse after using one of the ctors which don't do it
+ void SetCmdLine(int argc, char **argv);
+ void SetCmdLine(const wxString& cmdline);
+
+ // not virtual, don't use this class polymorphically
+ ~wxCmdLineParser();
+
+ // set different parser options
+ // ----------------------------
+
+ // by default, '-' is switch char under Unix, '-' or '/' under Win:
+ // switchChars contains all characters with which an option or switch may
+ // start
+ void SetSwitchChars(const wxString& switchChars);
+
+ // long options are not POSIX-compliant, this option allows to disable them
+ void EnableLongOptions(bool enable = TRUE);
+ void DisableLongOptions() { EnableLongOptions(FALSE); }
+
+ // construct the cmd line description
+ // ----------------------------------
+
+ // take the cmd line description from the wxCMD_LINE_NONE terminated table
+ void SetDesc(const wxCmdLineEntryDesc *desc);
+
+ // a switch: i.e. an option without value
+ void AddSwitch(const wxString& name, const wxString& lng = wxEmptyString,
+ const wxString& desc = wxEmptyString,
+ int flags = 0);
+
+ // an option taking a value of the given type
+ void AddOption(const wxString& name, const wxString& lng = wxEmptyString,
+ const wxString& desc = wxEmptyString,
+ wxCmdLineParamType type = wxCMD_LINE_VAL_STRING,
+ int flags = 0);
+
+ // a parameter
+ void AddParam(const wxString& desc = wxEmptyString,
+ wxCmdLineParamType type = wxCMD_LINE_VAL_STRING,
+ int flags = 0);
+
+ // actions
+ // -------
+
+ // parse the command line, return 0 if ok, -1 if "-h" or "--help" option
+ // was encountered and the help message was given or a positive value if a
+ // syntax error occured
+ int Parse();
+
+ // give the usage message describing all program options
+ void Usage();
+
+ // get the command line arguments
+ // ------------------------------
+
+ // returns TRUE if the given switch was found
+ bool Found(const wxString& name) const;
+
+ // returns TRUE if an option taking a string value was found and stores the
+ // value in the provided pointer
+ bool Found(const wxString& name, wxString *value) const;
+
+ // returns TRUE if an option taking an integer value was found and stores
+ // the value in the provided pointer
+ bool Found(const wxString& name, long *value) const;
+
+ // returns TRUE if an option taking a date value was found and stores the
+ // value in the provided pointer
+ bool Found(const wxString& name, wxDateTime *value) const;
+
+ // gets the number of parameters found
+ size_t GetParamCount() const;
+
+ // gets the value of Nth parameter (as string only for now)
+ wxString GetParam(size_t n) const;
+
+private:
+ // common part of all ctors
+ void Init();
+
+ struct wxCmdLineParserData *m_data;
+};
+
+#endif // _WX_CMDLINE_H_
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: common/cmdline.cpp
+// Purpose: wxCmdLineParser implementation
+// Author: Vadim Zeitlin
+// Modified by:
+// Created: 05.01.00
+// RCS-ID: $Id$
+// Copyright: (c) 2000 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence: wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+ #pragma implementation "cmdline.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+ #include "wx/string.h"
+ #include "wx/log.h"
+ #include "wx/intl.h"
+ #include "wx/dynarray.h"
+#endif //WX_PRECOMP
+
+#include "wx/datetime.h"
+#include "wx/cmdline.h"
+
+// ----------------------------------------------------------------------------
+// private functions
+// ----------------------------------------------------------------------------
+
+static wxString GetTypeName(wxCmdLineParamType type);
+
+// ----------------------------------------------------------------------------
+// private classes
+// ----------------------------------------------------------------------------
+
+// an internal representation of an option
+struct wxCmdLineOption
+{
+ wxCmdLineOption(wxCmdLineEntryType k,
+ const wxString& shrt,
+ const wxString& lng,
+ const wxString& desc,
+ wxCmdLineParamType typ,
+ int fl)
+ {
+ kind = k;
+
+ shortName = shrt;
+ longName = lng;
+ description = desc;
+
+ type = typ;
+ flags = fl;
+
+ m_hasVal = FALSE;
+ }
+
+ // can't use union easily here, so just store all possible data fields, we
+ // don't waste much (might still use union later if the number of supported
+ // types increases, so always use the accessor functions and don't access
+ // the fields directly!)
+
+ void Check(wxCmdLineParamType typ) const
+ {
+ wxASSERT_MSG( type == typ, _T("type mismatch in wxCmdLineOption") );
+ }
+
+ long GetLongVal() const
+ { Check(wxCMD_LINE_VAL_NUMBER); return m_longVal; }
+ const wxString& GetStrVal() const
+ { Check(wxCMD_LINE_VAL_STRING); return m_strVal; }
+ const wxDateTime& GetDateVal() const
+ { Check(wxCMD_LINE_VAL_DATE); return m_dateVal; }
+
+ void SetLongVal(long val)
+ { Check(wxCMD_LINE_VAL_NUMBER); m_longVal = val; m_hasVal = TRUE; }
+ void SetStrVal(const wxString& val)
+ { Check(wxCMD_LINE_VAL_STRING); m_strVal = val; m_hasVal = TRUE; }
+ void SetDateVal(const wxDateTime val)
+ { Check(wxCMD_LINE_VAL_DATE); m_dateVal = val; m_hasVal = TRUE; }
+
+ void SetHasValue() { m_hasVal = TRUE; }
+ bool HasValue() const { return m_hasVal; }
+
+public:
+ wxCmdLineEntryType kind;
+ wxString shortName, longName, description;
+ wxCmdLineParamType type;
+ int flags;
+
+private:
+ bool m_hasVal;
+
+ long m_longVal;
+ wxString m_strVal;
+ wxDateTime m_dateVal;
+};
+
+struct wxCmdLineParam
+{
+ wxCmdLineParam(const wxString& desc,
+ wxCmdLineParamType typ,
+ int fl)
+ : description(desc)
+ {
+ type = typ;
+ flags = fl;
+ }
+
+ wxString description;
+ wxCmdLineParamType type;
+ int flags;
+};
+
+WX_DECLARE_OBJARRAY(wxCmdLineOption, wxArrayOptions);
+WX_DECLARE_OBJARRAY(wxCmdLineParam, wxArrayParams);
+
+#include "wx/arrimpl.cpp"
+
+WX_DEFINE_OBJARRAY(wxArrayOptions);
+WX_DEFINE_OBJARRAY(wxArrayParams);
+
+// the parser internal state
+struct wxCmdLineParserData
+{
+ // options
+ wxString m_switchChars; // characters which may start an option
+
+ bool m_enableLongOptions; // TRUE if long options are enabled
+
+ // cmd line data
+ wxArrayString m_arguments; // == argv, argc == m_arguments.GetCount()
+ wxArrayOptions m_options; // all possible options and switchrs
+ wxArrayParams m_paramDesc; // description of all possible params
+ wxArrayString m_parameters; // all params found
+
+ // methods
+ wxCmdLineParserData();
+ void SetArguments(int argc, char **argv);
+ void SetArguments(const wxString& cmdline);
+
+ int FindOption(const wxString& name);
+ int FindOptionByLongName(const wxString& name);
+};
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxCmdLineParserData
+// ----------------------------------------------------------------------------
+
+wxCmdLineParserData::wxCmdLineParserData()
+{
+ m_enableLongOptions = TRUE;
+#ifdef __UNIX_LIKE__
+ m_switchChars = _T("-");
+#else // !Unix
+ m_switchChars = _T("/-");
+#endif
+}
+
+void wxCmdLineParserData::SetArguments(int argc, char **argv)
+{
+ m_arguments.Empty();
+
+ for ( int n = 0; n < argc; n++ )
+ {
+ m_arguments.Add(argv[n]);
+ }
+}
+
+void wxCmdLineParserData::SetArguments(const wxString& cmdline)
+{
+ // either use wxMSW wxApp::ConvertToStandardCommandArgs() or move its logic
+ // here and use this method from it - but don't duplicate the code
+
+ wxFAIL_MSG(_T("TODO"));
+}
+
+int wxCmdLineParserData::FindOption(const wxString& name)
+{
+ size_t count = m_options.GetCount();
+ for ( size_t n = 0; n < count; n++ )
+ {
+ if ( m_options[n].shortName == name )
+ {
+ // found
+ return n;
+ }
+ }
+
+ return wxNOT_FOUND;
+}
+
+int wxCmdLineParserData::FindOptionByLongName(const wxString& name)
+{
+ size_t count = m_options.GetCount();
+ for ( size_t n = 0; n < count; n++ )
+ {
+ if ( m_options[n].longName == name )
+ {
+ // found
+ return n;
+ }
+ }
+
+ return wxNOT_FOUND;
+}
+
+// ----------------------------------------------------------------------------
+// construction and destruction
+// ----------------------------------------------------------------------------
+
+void wxCmdLineParser::Init()
+{
+ m_data = new wxCmdLineParserData;
+}
+
+void wxCmdLineParser::SetCmdLine(int argc, char **argv)
+{
+ m_data->SetArguments(argc, argv);
+}
+
+void wxCmdLineParser::SetCmdLine(const wxString& cmdline)
+{
+ m_data->SetArguments(cmdline);
+}
+
+wxCmdLineParser::~wxCmdLineParser()
+{
+ delete m_data;
+}
+
+// ----------------------------------------------------------------------------
+// options
+// ----------------------------------------------------------------------------
+
+void wxCmdLineParser::SetSwitchChars(const wxString& switchChars)
+{
+ m_data->m_switchChars = switchChars;
+}
+
+void wxCmdLineParser::EnableLongOptions(bool enable)
+{
+ m_data->m_enableLongOptions = enable;
+}
+
+// ----------------------------------------------------------------------------
+// command line construction
+// ----------------------------------------------------------------------------
+
+void wxCmdLineParser::SetDesc(const wxCmdLineEntryDesc *desc)
+{
+ for ( ;; desc++ )
+ {
+ switch ( desc->kind )
+ {
+ case wxCMD_LINE_SWITCH:
+ AddSwitch(desc->shortName, desc->longName, desc->description);
+ break;
+
+ case wxCMD_LINE_OPTION:
+ AddOption(desc->shortName, desc->longName, desc->description,
+ desc->type, desc->flags);
+ break;
+
+ case wxCMD_LINE_PARAM:
+ AddParam(desc->description, desc->type, desc->flags);
+ break;
+
+ default:
+ wxFAIL_MSG( _T("unknown command line entry type") );
+ // still fall through
+
+ case wxCMD_LINE_NONE:
+ return;
+ }
+ }
+}
+
+void wxCmdLineParser::AddSwitch(const wxString& shortName,
+ const wxString& longName,
+ const wxString& desc,
+ int flags)
+{
+ wxASSERT_MSG( m_data->FindOption(shortName) == wxNOT_FOUND,
+ _T("duplicate switch") );
+
+ wxCmdLineOption *option = new wxCmdLineOption(wxCMD_LINE_SWITCH,
+ shortName, longName, desc,
+ wxCMD_LINE_VAL_NONE, flags);
+
+ m_data->m_options.Add(option);
+}
+
+void wxCmdLineParser::AddOption(const wxString& shortName,
+ const wxString& longName,
+ const wxString& desc,
+ wxCmdLineParamType type,
+ int flags)
+{
+ wxASSERT_MSG( m_data->FindOption(shortName) == wxNOT_FOUND,
+ _T("duplicate option") );
+
+ wxCmdLineOption *option = new wxCmdLineOption(wxCMD_LINE_OPTION,
+ shortName, longName, desc,
+ type, flags);
+
+ m_data->m_options.Add(option);
+}
+
+void wxCmdLineParser::AddParam(const wxString& desc,
+ wxCmdLineParamType type,
+ int flags)
+{
+ // do some consistency checks: a required parameter can't follow an
+ // optional one and nothing should follow a parameter with MULTIPLE flag
+#ifdef __WXDEBUG__
+ if ( !m_data->m_paramDesc.IsEmpty() )
+ {
+ wxCmdLineParam& param = m_data->m_paramDesc.Last();
+
+ wxASSERT_MSG( !(param.flags & wxCMD_LINE_PARAM_MULTIPLE),
+ _T("all parameters after the one with "
+ "wxCMD_LINE_PARAM_MULTIPLE style will be ignored") );
+
+ if ( !(flags & wxCMD_LINE_PARAM_OPTIONAL) )
+ {
+ wxASSERT_MSG( !(param.flags & wxCMD_LINE_PARAM_OPTIONAL),
+ _T("a required parameter can't follow an "
+ "optional one") );
+ }
+ }
+#endif // Debug
+
+ wxCmdLineParam *param = new wxCmdLineParam(desc, type, flags);
+
+ m_data->m_paramDesc.Add(param);
+}
+
+// ----------------------------------------------------------------------------
+// access to parse command line
+// ----------------------------------------------------------------------------
+
+bool wxCmdLineParser::Found(const wxString& name) const
+{
+ int i = m_data->FindOption(name);
+ wxCHECK_MSG( i != wxNOT_FOUND, FALSE, _T("unknown switch") );
+
+ wxCmdLineOption& opt = m_data->m_options[(size_t)i];
+ if ( !opt.HasValue() )
+ return FALSE;
+
+ return TRUE;
+}
+
+bool wxCmdLineParser::Found(const wxString& name, wxString *value) const
+{
+ int i = m_data->FindOption(name);
+ wxCHECK_MSG( i != wxNOT_FOUND, FALSE, _T("unknown option") );
+
+ wxCmdLineOption& opt = m_data->m_options[(size_t)i];
+ if ( !opt.HasValue() )
+ return FALSE;
+
+ wxCHECK_MSG( value, FALSE, _T("NULL pointer in wxCmdLineOption::Found") );
+
+ *value = opt.GetStrVal();
+
+ return TRUE;
+}
+
+bool wxCmdLineParser::Found(const wxString& name, long *value) const
+{
+ int i = m_data->FindOption(name);
+ wxCHECK_MSG( i != wxNOT_FOUND, FALSE, _T("unknown option") );
+
+ wxCmdLineOption& opt = m_data->m_options[(size_t)i];
+ if ( !opt.HasValue() )
+ return FALSE;
+
+ wxCHECK_MSG( value, FALSE, _T("NULL pointer in wxCmdLineOption::Found") );
+
+ *value = opt.GetLongVal();
+
+ return TRUE;
+}
+
+bool wxCmdLineParser::Found(const wxString& name, wxDateTime *value) const
+{
+ int i = m_data->FindOption(name);
+ wxCHECK_MSG( i != wxNOT_FOUND, FALSE, _T("unknown option") );
+
+ wxCmdLineOption& opt = m_data->m_options[(size_t)i];
+ if ( !opt.HasValue() )
+ return FALSE;
+
+ wxCHECK_MSG( value, FALSE, _T("NULL pointer in wxCmdLineOption::Found") );
+
+ *value = opt.GetDateVal();
+
+ return TRUE;
+}
+
+size_t wxCmdLineParser::GetParamCount() const
+{
+ return m_data->m_parameters.GetCount();
+}
+
+wxString wxCmdLineParser::GetParam(size_t n) const
+{
+ return m_data->m_parameters[n];
+}
+
+// ----------------------------------------------------------------------------
+// the real work is done here
+// ----------------------------------------------------------------------------
+
+int wxCmdLineParser::Parse()
+{
+ bool maybeOption = TRUE; // can the following arg be an option?
+ bool ok = TRUE; // TRUE until an error is detected
+ bool helpRequested = FALSE; // TRUE if "-h" was given
+ bool hadRepeatableParam = FALSE; // TRUE if found param with MULTIPLE flag
+
+ size_t currentParam = 0; // the index in m_paramDesc
+
+ size_t countParam = m_data->m_paramDesc.GetCount();
+
+ // parse everything
+ wxString arg;
+ size_t count = m_data->m_arguments.GetCount();
+ for ( size_t n = 1; ok && (n < count); n++ ) // 0 is program name
+ {
+ arg = m_data->m_arguments[n];
+
+ // special case: "--" should be discarded and all following arguments
+ // should be considered as parameters, even if they start with '-' and
+ // not like options (this is POSIX-like)
+ if ( arg == _T("--") )
+ {
+ maybeOption = FALSE;
+
+ continue;
+ }
+
+ // empty argument or just '-' is not an option but a parameter
+ if ( maybeOption && arg.length() > 1 &&
+ wxStrchr(m_data->m_switchChars, arg[0u]) )
+ {
+ bool isLong;
+ wxString name;
+ int optInd = wxNOT_FOUND; // init to suppress warnings
+
+ // an option or a switch: find whether it's a long or a short one
+ if ( m_data->m_enableLongOptions &&
+ arg[0u] == _T('-') && arg[1u] == _T('-') )
+ {
+ // a long one
+ isLong = TRUE;
+
+ const wxChar *p = arg.c_str() + 2;
+ while ( wxIsalpha(*p) || (*p == _T('-')) )
+ {
+ name += *p++;
+ }
+
+ optInd = m_data->FindOptionByLongName(name);
+ if ( optInd == wxNOT_FOUND )
+ {
+ wxLogError(_("Unknown long option '%s'"), name.c_str());
+ }
+ }
+ else
+ {
+ isLong = FALSE;
+
+ // a short one: as they can be cumulated, we try to find the
+ // longest substring which is a valid option
+ const wxChar *p = arg.c_str() + 1;
+ while ( wxIsalpha(*p) )
+ {
+ name += *p++;
+ }
+
+ size_t len = name.length();
+ do
+ {
+ if ( len == 0 )
+ {
+ // we couldn't find a valid option name in the
+ // beginning of this string
+ wxLogError(_("Unknown option '%s'"), name.c_str());
+
+ break;
+ }
+ else
+ {
+ optInd = m_data->FindOption(name.Left(len));
+
+ // will try with one character less the next time
+ len--;
+ }
+ }
+ while ( optInd == wxNOT_FOUND );
+
+ if ( (len > 0) && (len != name.length()) )
+ {
+ // our option is only part of this argument, there is
+ // something else in it - it is either the value of this
+ // option or other switches if it is a switch
+ if ( m_data->m_options[(size_t)optInd].kind
+ == wxCMD_LINE_SWITCH )
+ {
+ // pretend that all the rest of the argument is the
+ // next argument, in fact
+ wxString arg2 = arg[0u];
+ arg2 += name.Mid(len);
+
+ m_data->m_arguments.Insert(arg2, n + 1);
+ }
+ //else: it's our value, we'll deal with it below
+ }
+ }
+
+ if ( optInd == wxNOT_FOUND )
+ {
+ ok = FALSE;
+
+ continue; // will break, in fact
+ }
+
+ wxCmdLineOption& opt = m_data->m_options[(size_t)optInd];
+ if ( opt.kind == wxCMD_LINE_SWITCH )
+ {
+ // nothing more to do
+ opt.SetHasValue();
+
+ if ( opt.flags & wxCMD_LINE_OPTION_HELP )
+ {
+ helpRequested = TRUE;
+
+ // it's not an error, but we still stop here
+ ok = FALSE;
+ }
+ }
+ else
+ {
+ // get the value
+
+ // +1 for leading '-'
+ const wxChar *p = arg.c_str() + 1 + name.length();
+ if ( isLong )
+ {
+ p++; // for another leading '-'
+
+ if ( *p++ != _T('=') )
+ {
+ wxLogError(_("Option '%s' requires a value, '=' "
+ "expected."), name.c_str());
+
+ ok = FALSE;
+ }
+ }
+ else
+ {
+ switch ( *p )
+ {
+ case _T(':'):
+ // the value follows
+ p++;
+ break;
+
+ case 0:
+ // the value is in the next argument
+ if ( ++n == count )
+ {
+ // ... but there is none
+ wxLogError(_("Option '%s' requires a value."),
+ name.c_str());
+
+ ok = FALSE;
+ }
+ else
+ {
+ // ... take it from there
+ p = m_data->m_arguments[n].c_str();
+ }
+ break;
+
+ default:
+ // the value is right here
+ ;
+ }
+ }
+
+ if ( ok )
+ {
+ wxString value = p;
+ switch ( opt.type )
+ {
+ default:
+ wxFAIL_MSG( _T("unknown option type") );
+ // still fall through
+
+ case wxCMD_LINE_VAL_STRING:
+ opt.SetStrVal(value);
+ break;
+
+ case wxCMD_LINE_VAL_NUMBER:
+ {
+ long val;
+ if ( value.ToLong(&val) )
+ {
+ opt.SetLongVal(val);
+ }
+ else
+ {
+ wxLogError(_("'%s' is not a correct "
+ "numeric value for option "
+ "'%s'."),
+ value.c_str(), name.c_str());
+
+ ok = FALSE;
+ }
+ }
+ break;
+
+ case wxCMD_LINE_VAL_DATE:
+ {
+ wxDateTime dt;
+ const wxChar *res = dt.ParseDate(value);
+ if ( !res || *res )
+ {
+ wxLogError(_("Options '%s': '%s' cannot "
+ "be converted to a date."),
+ name.c_str(), value.c_str());
+
+ ok = FALSE;
+ }
+ else
+ {
+ opt.SetDateVal(dt);
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ // a parameter
+ if ( currentParam < countParam )
+ {
+ wxCmdLineParam& param = m_data->m_paramDesc[currentParam];
+
+ // TODO check the param type
+
+ m_data->m_parameters.Add(arg);
+
+ if ( !(param.flags & wxCMD_LINE_PARAM_MULTIPLE) )
+ {
+ currentParam++;
+ }
+ else
+ {
+ wxASSERT_MSG( currentParam == countParam - 1,
+ _T("all parameters after the one with "
+ "wxCMD_LINE_PARAM_MULTIPLE style "
+ "are ignored") );
+
+ // remember that we did have this last repeatable parameter
+ hadRepeatableParam = TRUE;
+ }
+ }
+ else
+ {
+ wxLogError(_("Unexpected parameter '%s'"), arg.c_str());
+
+ ok = FALSE;
+ }
+ }
+ }
+
+ // verify that all mandatory options were given
+ if ( ok )
+ {
+ size_t countOpt = m_data->m_options.GetCount();
+ for ( size_t n = 0; ok && (n < countOpt); n++ )
+ {
+ wxCmdLineOption& opt = m_data->m_options[n];
+ if ( (opt.flags & wxCMD_LINE_OPTION_MANDATORY) && !opt.HasValue() )
+ {
+ wxString optName;
+ if ( !opt.longName )
+ {
+ optName = opt.shortName;
+ }
+ else
+ {
+ optName.Printf(_("%s (or %s)"),
+ opt.shortName.c_str(),
+ opt.longName.c_str());
+ }
+
+ wxLogError(_("The value for the option '%s' must be specified."),
+ optName.c_str());
+
+ ok = FALSE;
+ }
+ }
+
+ for ( ; ok && (currentParam < countParam); currentParam++ )
+ {
+ wxCmdLineParam& param = m_data->m_paramDesc[currentParam];
+ if ( (currentParam == countParam - 1) &&
+ (param.flags & wxCMD_LINE_PARAM_MULTIPLE) &&
+ hadRepeatableParam )
+ {
+ // special case: currentParam wasn't incremented, but we did
+ // have it, so don't give error
+ continue;
+ }
+
+ if ( !(param.flags & wxCMD_LINE_PARAM_OPTIONAL) )
+ {
+ wxLogError(_("The required parameter '%s' was not specified."),
+ param.description.c_str());
+
+ ok = FALSE;
+ }
+ }
+ }
+
+ if ( !ok )
+ {
+ Usage();
+ }
+
+ return ok ? 0 : helpRequested ? -1 : 1;
+}
+
+// ----------------------------------------------------------------------------
+// give the usage message
+// ----------------------------------------------------------------------------
+
+void wxCmdLineParser::Usage()
+{
+ wxString brief, detailed;
+ brief.Printf(_("Usage: %s"), wxTheApp->GetAppName().c_str());
+
+ size_t n, count = m_data->m_options.GetCount();
+ for ( n = 0; n < count; n++ )
+ {
+ wxCmdLineOption& opt = m_data->m_options[n];
+
+ brief << _T(' ');
+ if ( !(opt.flags & wxCMD_LINE_OPTION_MANDATORY) )
+ {
+ brief << _T('[');
+ }
+
+ brief << _T('-') << opt.shortName;
+ detailed << _T(" -") << opt.shortName;
+ if ( !!opt.longName )
+ {
+ detailed << _T(" --") << opt.longName;
+ }
+
+ if ( opt.kind != wxCMD_LINE_SWITCH )
+ {
+ wxString val;
+ val << _T('<') << GetTypeName(opt.type) << _T('>');
+ brief << _T(' ') << val;
+ detailed << (!opt.longName ? _T(':') : _T('=')) << val;
+ }
+
+ if ( !(opt.flags & wxCMD_LINE_OPTION_MANDATORY) )
+ {
+ brief << _T(']');
+ }
+
+ detailed << _T('\t') << opt.description << _T('\n');
+ }
+
+ count = m_data->m_paramDesc.GetCount();
+ for ( n = 0; n < count; n++ )
+ {
+ wxCmdLineParam& param = m_data->m_paramDesc[n];
+
+ brief << _T(' ');
+ if ( param.flags & wxCMD_LINE_PARAM_OPTIONAL )
+ {
+ brief << _T('[');
+ }
+
+ brief << param.description;
+
+ if ( param.flags & wxCMD_LINE_PARAM_MULTIPLE )
+ {
+ brief << _T("...");
+ }
+
+ if ( param.flags & wxCMD_LINE_PARAM_OPTIONAL )
+ {
+ brief << _T(']');
+ }
+ }
+
+ wxLogMessage(brief);
+ wxLogMessage(detailed);
+}
+
+// ----------------------------------------------------------------------------
+// global functions
+// ----------------------------------------------------------------------------
+
+static wxString GetTypeName(wxCmdLineParamType type)
+{
+ wxString s;
+ switch ( type )
+ {
+ default:
+ wxFAIL_MSG( _T("unknown option type") );
+ // still fall through
+
+ case wxCMD_LINE_VAL_STRING: s = _("str"); break;
+ case wxCMD_LINE_VAL_NUMBER: s = _("num"); break;
+ case wxCMD_LINE_VAL_DATE: s = _("date"); break;
+ }
+
+ return s;
+}