wxCMD_LINE_SWITCH,
wxCMD_LINE_OPTION,
wxCMD_LINE_PARAM,
+ wxCMD_LINE_USAGE_TEXT,
wxCMD_LINE_NONE ///< Use this to terminate the list.
};
unlike a switch. For example, @c -o: @c filename might be an
option for specifying the name of the output file.
- @b parameter: This is a required program argument.
+ - @b text: This is a text which can be shown in usage information.
@section cmdlineparser_construction Construction
The same holds for command line description: it can be specified either in
the constructor (with or without the command line itself) or constructed
- later using either SetDesc() or combination of AddSwitch(), AddOption() and
- AddParam() methods.
+ later using either SetDesc() or combination of AddSwitch(), AddOption(),
+ AddParam() and AddUsageText() methods.
Using constructors or SetDesc() uses a (usually const static) table
containing the command line description. If you want to decide which
const wxString& desc = wxEmptyString,
int flags = 0);
+ /**
+ Add a string @a text to the command line description shown by Usage().
+
+ @since 2.9.0
+ */
+ void AddUsageText(const wxString& text);
+
/**
Returns @true if long options are enabled, otherwise @false.
wxCmdLineParamType typ,
int fl)
{
- wxASSERT_MSG( !shrt.empty() || !lng.empty(),
- _T("option should have at least one name") );
-
- wxASSERT_MSG
- (
- GetShortOptionName(shrt.begin(), shrt.end()).Len() == shrt.Len(),
- wxT("Short option contains invalid characters")
- );
-
- wxASSERT_MSG
- (
- GetLongOptionName(lng.begin(), lng.end()).Len() == lng.Len(),
- wxT("Long option contains invalid characters")
- );
+ // wxCMD_LINE_USAGE_TEXT uses only description, shortName and longName is empty
+ #ifdef __WXDEBUG__
+ if ( k != wxCMD_LINE_USAGE_TEXT )
+ {
+ wxASSERT_MSG
+ (
+ !shrt.empty() || !lng.empty(),
+ wxT("option should have at least one name")
+ );
+
+ wxASSERT_MSG
+ (
+ GetShortOptionName(shrt.begin(), shrt.end()).Len() == shrt.Len(),
+ wxT("Short option contains invalid characters")
+ );
+
+ wxASSERT_MSG
+ (
+ GetLongOptionName(lng.begin(), lng.end()).Len() == lng.Len(),
+ wxT("Long option contains invalid characters")
+ );
+ }
+ #endif // __WXDEBUG__
kind = k;
desc->type, desc->flags);
break;
+ case wxCMD_LINE_USAGE_TEXT:
+ AddUsageText(wxGetTranslation(desc->description));
+ break;
+
default:
wxFAIL_MSG( _T("unknown command line entry type") );
// still fall through
m_data->m_paramDesc.Add(param);
}
+void wxCmdLineParser::AddUsageText(const wxString& text)
+{
+ wxASSERT_MSG( !text.empty(), wxT("text can't be empty") );
+
+ wxCmdLineOption *option = new wxCmdLineOption(wxCMD_LINE_USAGE_TEXT,
+ wxEmptyString, wxEmptyString,
+ text, wxCMD_LINE_VAL_NONE, 0);
+
+ m_data->m_options.Add(option);
+}
+
// ----------------------------------------------------------------------------
// access to parse command line
// ----------------------------------------------------------------------------
for ( n = 0; n < count; n++ )
{
wxCmdLineOption& opt = m_data->m_options[n];
+ wxString option;
- usage << _T(' ');
- if ( !(opt.flags & wxCMD_LINE_OPTION_MANDATORY) )
+ if ( opt.kind != wxCMD_LINE_USAGE_TEXT )
{
- usage << _T('[');
- }
+ usage << _T(' ');
+ if ( !(opt.flags & wxCMD_LINE_OPTION_MANDATORY) )
+ {
+ usage << _T('[');
+ }
- if ( !opt.shortName.empty() )
- {
- usage << chSwitch << opt.shortName;
- }
- else if ( areLongOptionsEnabled && !opt.longName.empty() )
- {
- usage << _T("--") << opt.longName;
- }
- else
- {
- if (!opt.longName.empty())
+ if ( !opt.shortName.empty() )
{
- wxFAIL_MSG( wxT("option with only a long name while long ")
- wxT("options are disabled") );
+ usage << chSwitch << opt.shortName;
+ }
+ else if ( areLongOptionsEnabled && !opt.longName.empty() )
+ {
+ usage << _T("--") << opt.longName;
}
else
{
- wxFAIL_MSG( _T("option without neither short nor long name") );
+ if (!opt.longName.empty())
+ {
+ wxFAIL_MSG( wxT("option with only a long name while long ")
+ wxT("options are disabled") );
+ }
+ else
+ {
+ wxFAIL_MSG( _T("option without neither short nor long name") );
+ }
}
- }
- wxString option;
-
- if ( !opt.shortName.empty() )
- {
- option << _T(" ") << chSwitch << opt.shortName;
- }
+ if ( !opt.shortName.empty() )
+ {
+ option << _T(" ") << chSwitch << opt.shortName;
+ }
- if ( areLongOptionsEnabled && !opt.longName.empty() )
- {
- option << (option.empty() ? _T(" ") : _T(", "))
- << _T("--") << opt.longName;
- }
+ if ( areLongOptionsEnabled && !opt.longName.empty() )
+ {
+ option << (option.empty() ? _T(" ") : _T(", "))
+ << _T("--") << opt.longName;
+ }
- if ( opt.kind != wxCMD_LINE_SWITCH )
- {
- wxString val;
- val << _T('<') << GetTypeName(opt.type) << _T('>');
- usage << _T(' ') << val;
- option << (!opt.longName ? _T(':') : _T('=')) << val;
- }
+ if ( opt.kind != wxCMD_LINE_SWITCH )
+ {
+ wxString val;
+ val << _T('<') << GetTypeName(opt.type) << _T('>');
+ usage << _T(' ') << val;
+ option << (!opt.longName ? _T(':') : _T('=')) << val;
+ }
- if ( !(opt.flags & wxCMD_LINE_OPTION_MANDATORY) )
- {
- usage << _T(']');
+ if ( !(opt.flags & wxCMD_LINE_OPTION_MANDATORY) )
+ {
+ usage << _T(']');
+ }
}
namesOptions.push_back(option);
usage << _T('\n') << stdDesc;
len = namesOptions[n].length();
- usage << namesOptions[n]
- << wxString(_T(' '), lenMax - len) << _T('\t')
- << descOptions[n]
- << _T('\n');
+ // desc contains text if name is empty
+ if (len == 0)
+ {
+ usage << descOptions[n] << _T('\n');
+ }
+ else
+ {
+ usage << namesOptions[n]
+ << wxString(_T(' '), lenMax - len) << _T('\t')
+ << descOptions[n]
+ << _T('\n');
+ }
}
return usage;
private:
CPPUNIT_TEST_SUITE( CmdLineTestCase );
CPPUNIT_TEST( ConvertStringTestCase );
+ CPPUNIT_TEST( Usage );
CPPUNIT_TEST_SUITE_END();
void ConvertStringTestCase();
+ void Usage();
DECLARE_NO_COPY_CLASS(CmdLineTestCase)
};
#undef WX_ASSERT_ARGS_EQUAL
}
+
+void CmdLineTestCase::Usage()
+{
+ // check that Usage() returns roughly what we expect (don't check all the
+ // details, its format can change in the future)
+ static const wxCmdLineEntryDesc desc[] =
+ {
+ { wxCMD_LINE_USAGE_TEXT, NULL, NULL, "Verbosity options" },
+ { wxCMD_LINE_SWITCH, "v", "verbose", "be verbose" },
+ { wxCMD_LINE_SWITCH, "q", "quiet", "be quiet" },
+
+ { wxCMD_LINE_USAGE_TEXT, NULL, NULL, "Output options" },
+ { wxCMD_LINE_OPTION, "o", "output", "output file" },
+ { wxCMD_LINE_OPTION, "s", "size", "output block size", wxCMD_LINE_VAL_NUMBER },
+ { wxCMD_LINE_OPTION, "d", "date", "output file date", wxCMD_LINE_VAL_DATE },
+ { wxCMD_LINE_OPTION, "f", "double", "output double", wxCMD_LINE_VAL_DOUBLE },
+
+ { wxCMD_LINE_PARAM, NULL, NULL, "input file", },
+
+ { wxCMD_LINE_USAGE_TEXT, NULL, NULL, "\nEven more usage text" },
+ { wxCMD_LINE_NONE }
+ };
+
+ wxCmdLineParser p(desc);
+ const wxArrayString usageLines = wxSplit(p.GetUsageString(), '\n');
+
+ enum
+ {
+ Line_Synopsis,
+ Line_Text_Verbosity,
+ Line_Verbose,
+ Line_Quiet,
+ Line_Text_Output,
+ Line_Output_File,
+ Line_Output_Size,
+ Line_Output_Date,
+ Line_Output_Double,
+ Line_Text_Dummy1,
+ Line_Text_Dummy2,
+ Line_Last,
+ Line_Max
+ };
+
+ WX_ASSERT_SIZET_EQUAL( Line_Max, usageLines.size() );
+ WX_ASSERT_STR_EQUAL("Verbosity options", usageLines[Line_Text_Verbosity]);
+ WX_ASSERT_STR_EQUAL("", usageLines[Line_Text_Dummy1]);
+ WX_ASSERT_STR_EQUAL("Even more usage text", usageLines[Line_Text_Dummy2]);
+ WX_ASSERT_STR_EQUAL("", usageLines[Line_Last]);
+}