add wxCmdLineParser::AddUsageText() and wxCMD_LINE_USAGE_TEXT (modified patch 1957542)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@53567 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2008-05-12 00:03:06 +00:00
parent 16b627b06a
commit e559d790fb
5 changed files with 158 additions and 60 deletions

View File

@@ -248,6 +248,7 @@ All:
wxQueueEvent() replacing wxPostEvent(). wxQueueEvent() replacing wxPostEvent().
- wxString now uses std::[w]string internally by default, meaning that it is - wxString now uses std::[w]string internally by default, meaning that it is
now thread-safe if the standard library provided with your compiler is. now thread-safe if the standard library provided with your compiler is.
- Added wxCmdLineParser::AddUsageText() (Marcin 'Malcom' Malich)
All (Unix): All (Unix):

View File

@@ -55,6 +55,7 @@ enum wxCmdLineEntryType
wxCMD_LINE_SWITCH, wxCMD_LINE_SWITCH,
wxCMD_LINE_OPTION, wxCMD_LINE_OPTION,
wxCMD_LINE_PARAM, wxCMD_LINE_PARAM,
wxCMD_LINE_USAGE_TEXT,
wxCMD_LINE_NONE // to terminate the list wxCMD_LINE_NONE // to terminate the list
}; };
@@ -178,6 +179,9 @@ public:
wxCmdLineParamType type = wxCMD_LINE_VAL_STRING, wxCmdLineParamType type = wxCMD_LINE_VAL_STRING,
int flags = 0); int flags = 0);
// add an explanatory text to be shown to the user in help
void AddUsageText(const wxString& text);
// actions // actions
// ------- // -------
@@ -253,4 +257,3 @@ public:
#endif // wxUSE_CMDLINE_PARSER/!wxUSE_CMDLINE_PARSER #endif // wxUSE_CMDLINE_PARSER/!wxUSE_CMDLINE_PARSER
#endif // _WX_CMDLINE_H_ #endif // _WX_CMDLINE_H_

View File

@@ -55,6 +55,7 @@ enum wxCmdLineEntryType
wxCMD_LINE_SWITCH, wxCMD_LINE_SWITCH,
wxCMD_LINE_OPTION, wxCMD_LINE_OPTION,
wxCMD_LINE_PARAM, wxCMD_LINE_PARAM,
wxCMD_LINE_USAGE_TEXT,
wxCMD_LINE_NONE ///< Use this to terminate the list. wxCMD_LINE_NONE ///< Use this to terminate the list.
}; };
@@ -117,6 +118,7 @@ struct wxCmdLineEntryDesc
unlike a switch. For example, @c -o: @c filename might be an unlike a switch. For example, @c -o: @c filename might be an
option for specifying the name of the output file. option for specifying the name of the output file.
- @b parameter: This is a required program argument. - @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 @section cmdlineparser_construction Construction
@@ -137,8 +139,8 @@ struct wxCmdLineEntryDesc
The same holds for command line description: it can be specified either in The same holds for command line description: it can be specified either in
the constructor (with or without the command line itself) or constructed the constructor (with or without the command line itself) or constructed
later using either SetDesc() or combination of AddSwitch(), AddOption() and later using either SetDesc() or combination of AddSwitch(), AddOption(),
AddParam() methods. AddParam() and AddUsageText() methods.
Using constructors or SetDesc() uses a (usually const static) table Using constructors or SetDesc() uses a (usually const static) table
containing the command line description. If you want to decide which containing the command line description. If you want to decide which
@@ -285,6 +287,13 @@ public:
const wxString& desc = wxEmptyString, const wxString& desc = wxEmptyString,
int flags = 0); 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. Returns @true if long options are enabled, otherwise @false.

View File

@@ -73,20 +73,29 @@ struct wxCmdLineOption
wxCmdLineParamType typ, wxCmdLineParamType typ,
int fl) int fl)
{ {
wxASSERT_MSG( !shrt.empty() || !lng.empty(), // wxCMD_LINE_USAGE_TEXT uses only description, shortName and longName is empty
_T("option should have at least one name") ); #ifdef __WXDEBUG__
if ( k != wxCMD_LINE_USAGE_TEXT )
{
wxASSERT_MSG
(
!shrt.empty() || !lng.empty(),
wxT("option should have at least one name")
);
wxASSERT_MSG wxASSERT_MSG
( (
GetShortOptionName(shrt.begin(), shrt.end()).Len() == shrt.Len(), GetShortOptionName(shrt.begin(), shrt.end()).Len() == shrt.Len(),
wxT("Short option contains invalid characters") wxT("Short option contains invalid characters")
); );
wxASSERT_MSG wxASSERT_MSG
( (
GetLongOptionName(lng.begin(), lng.end()).Len() == lng.Len(), GetLongOptionName(lng.begin(), lng.end()).Len() == lng.Len(),
wxT("Long option contains invalid characters") wxT("Long option contains invalid characters")
); );
}
#endif // __WXDEBUG__
kind = k; kind = k;
@@ -390,6 +399,10 @@ void wxCmdLineParser::SetDesc(const wxCmdLineEntryDesc *desc)
desc->type, desc->flags); desc->type, desc->flags);
break; break;
case wxCMD_LINE_USAGE_TEXT:
AddUsageText(wxGetTranslation(desc->description));
break;
default: default:
wxFAIL_MSG( _T("unknown command line entry type") ); wxFAIL_MSG( _T("unknown command line entry type") );
// still fall through // still fall through
@@ -458,6 +471,17 @@ void wxCmdLineParser::AddParam(const wxString& desc,
m_data->m_paramDesc.Add(param); 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 // access to parse command line
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -1036,58 +1060,60 @@ wxString wxCmdLineParser::GetUsageString() const
for ( n = 0; n < count; n++ ) for ( n = 0; n < count; n++ )
{ {
wxCmdLineOption& opt = m_data->m_options[n]; wxCmdLineOption& opt = m_data->m_options[n];
wxString option;
usage << _T(' '); if ( opt.kind != wxCMD_LINE_USAGE_TEXT )
if ( !(opt.flags & wxCMD_LINE_OPTION_MANDATORY) )
{ {
usage << _T('['); usage << _T(' ');
} if ( !(opt.flags & wxCMD_LINE_OPTION_MANDATORY) )
if ( !opt.shortName.empty() )
{
usage << chSwitch << opt.shortName;
}
else if ( areLongOptionsEnabled && !opt.longName.empty() )
{
usage << _T("--") << opt.longName;
}
else
{
if (!opt.longName.empty())
{ {
wxFAIL_MSG( wxT("option with only a long name while long ") usage << _T('[');
wxT("options are disabled") ); }
if ( !opt.shortName.empty() )
{
usage << chSwitch << opt.shortName;
}
else if ( areLongOptionsEnabled && !opt.longName.empty() )
{
usage << _T("--") << opt.longName;
} }
else 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() ) if ( areLongOptionsEnabled && !opt.longName.empty() )
{ {
option << _T(" ") << chSwitch << opt.shortName; option << (option.empty() ? _T(" ") : _T(", "))
} << _T("--") << opt.longName;
}
if ( areLongOptionsEnabled && !opt.longName.empty() ) if ( opt.kind != wxCMD_LINE_SWITCH )
{ {
option << (option.empty() ? _T(" ") : _T(", ")) wxString val;
<< _T("--") << opt.longName; val << _T('<') << GetTypeName(opt.type) << _T('>');
} usage << _T(' ') << val;
option << (!opt.longName ? _T(':') : _T('=')) << val;
}
if ( opt.kind != wxCMD_LINE_SWITCH ) if ( !(opt.flags & wxCMD_LINE_OPTION_MANDATORY) )
{ {
wxString val; usage << _T(']');
val << _T('<') << GetTypeName(opt.type) << _T('>'); }
usage << _T(' ') << val;
option << (!opt.longName ? _T(':') : _T('=')) << val;
}
if ( !(opt.flags & wxCMD_LINE_OPTION_MANDATORY) )
{
usage << _T(']');
} }
namesOptions.push_back(option); namesOptions.push_back(option);
@@ -1144,10 +1170,18 @@ wxString wxCmdLineParser::GetUsageString() const
usage << _T('\n') << stdDesc; usage << _T('\n') << stdDesc;
len = namesOptions[n].length(); len = namesOptions[n].length();
usage << namesOptions[n] // desc contains text if name is empty
<< wxString(_T(' '), lenMax - len) << _T('\t') if (len == 0)
<< descOptions[n] {
<< _T('\n'); usage << descOptions[n] << _T('\n');
}
else
{
usage << namesOptions[n]
<< wxString(_T(' '), lenMax - len) << _T('\t')
<< descOptions[n]
<< _T('\n');
}
} }
return usage; return usage;

View File

@@ -34,9 +34,11 @@ public:
private: private:
CPPUNIT_TEST_SUITE( CmdLineTestCase ); CPPUNIT_TEST_SUITE( CmdLineTestCase );
CPPUNIT_TEST( ConvertStringTestCase ); CPPUNIT_TEST( ConvertStringTestCase );
CPPUNIT_TEST( Usage );
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
void ConvertStringTestCase(); void ConvertStringTestCase();
void Usage();
DECLARE_NO_COPY_CLASS(CmdLineTestCase) DECLARE_NO_COPY_CLASS(CmdLineTestCase)
}; };
@@ -80,3 +82,52 @@ void CmdLineTestCase::ConvertStringTestCase()
#undef WX_ASSERT_ARGS_EQUAL #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]);
}