From 9f83044fb8785568e186bee64db4f98b7a9ac9c6 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 5 Jan 2000 02:41:18 +0000 Subject: [PATCH] 1. compilation fixes for TB_REPLACEBITMAP and FONTENUMPROC 2. added wxCmdLineParser class git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5246 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/cmdline.h | 193 ++++++++++ src/common/cmdline.cpp | 851 +++++++++++++++++++++++++++++++++++++++++ src/common/log.cpp | 6 +- src/msw/fontenum.cpp | 10 +- src/msw/tbar95.cpp | 52 ++- 5 files changed, 1091 insertions(+), 21 deletions(-) create mode 100644 include/wx/cmdline.h create mode 100644 src/common/cmdline.cpp diff --git a/include/wx/cmdline.h b/include/wx/cmdline.h new file mode 100644 index 0000000000..0b7576b8cf --- /dev/null +++ b/include/wx/cmdline.h @@ -0,0 +1,193 @@ +/////////////////////////////////////////////////////////////////////////////// +// 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 +// 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_ diff --git a/src/common/cmdline.cpp b/src/common/cmdline.cpp new file mode 100644 index 0000000000..f42ca0f098 --- /dev/null +++ b/src/common/cmdline.cpp @@ -0,0 +1,851 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: common/cmdline.cpp +// Purpose: wxCmdLineParser implementation +// Author: Vadim Zeitlin +// Modified by: +// Created: 05.01.00 +// RCS-ID: $Id$ +// Copyright: (c) 2000 Vadim Zeitlin +// 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; +} diff --git a/src/common/log.cpp b/src/common/log.cpp index 6d99576b99..076a9203e6 100644 --- a/src/common/log.cpp +++ b/src/common/log.cpp @@ -431,7 +431,11 @@ wxLog *wxLog::ms_pLogger = (wxLog *)NULL; bool wxLog::ms_doLog = TRUE; bool wxLog::ms_bAutoCreate = TRUE; -const wxChar *wxLog::ms_timestamp = wxT("%X"); // time only, no date +#if wxUSE_GUI + const wxChar *wxLog::ms_timestamp = wxT("%X"); // time only, no date +#else + const wxChar *wxLog::ms_timestamp = NULL; // save space +#endif wxTraceMask wxLog::ms_ulTraceMask = (wxTraceMask)0; wxArrayString wxLog::ms_aTraceMasks; diff --git a/src/msw/fontenum.cpp b/src/msw/fontenum.cpp index 8b9d993b14..49c26ef9ae 100644 --- a/src/msw/fontenum.cpp +++ b/src/msw/fontenum.cpp @@ -110,10 +110,14 @@ bool wxFontEnumeratorHelper::SetEncoding(wxFontEncoding encoding) return TRUE; } -#if defined(__GNUWIN32__) && !defined(__MINGW32__) - #define wxFONTENUMPROC int(*)(ENUMLOGFONTEX *, NEWTEXTMETRICEX*, int, LPARAM) +#if defined(__GNUWIN32__) + #if defined(__MINGW32__) + #define wxFONTENUMPROC FONTENUMEXPROC + #else + #define wxFONTENUMPROC int(*)(ENUMLOGFONTEX *, NEWTEXTMETRICEX*, int, LPARAM) + #endif #else - #define wxFONTENUMPROC FONTENUMEXPROC + #define wxFONTENUMPROC FONTENUMPROC #endif void wxFontEnumeratorHelper::DoEnumerate() diff --git a/src/msw/tbar95.cpp b/src/msw/tbar95.cpp index d60c8baa0f..5f9153e7b8 100644 --- a/src/msw/tbar95.cpp +++ b/src/msw/tbar95.cpp @@ -49,10 +49,7 @@ #ifndef __TWIN32__ -// I don't know what _OLD_ refers to so I'm reinstating the old -// ifdef (JACS). -// #ifdef __GNUWIN32_OLD__ -#if defined(__GNUWIN32__) && !defined(__MINGW32__) +#ifdef __GNUWIN32_OLD__ #include "wx/msw/gnuwin32/extra.h" #else #include @@ -407,21 +404,42 @@ bool wxToolBar::Realize() // Map to system colours wxMapBitmap(hBitmap, totalBitmapWidth, totalBitmapHeight); + int bitmapId = 0; + + bool addBitmap = TRUE; + if ( oldToolBarBitmap ) { - TBREPLACEBITMAP replaceBitmap; - replaceBitmap.hInstOld = NULL; - replaceBitmap.hInstNew = NULL; - replaceBitmap.nIDOld = (UINT) oldToolBarBitmap; - replaceBitmap.nIDNew = (UINT) hBitmap; - replaceBitmap.nButtons = nButtons; - if ( !::SendMessage(GetHwnd(), TB_REPLACEBITMAP, - 0, (LPARAM) &replaceBitmap) ) +#ifdef TB_REPLACEBITMAP + if ( wxTheApp->GetComCtl32Version() >= 400 ) { - wxFAIL_MSG(wxT("Could not add bitmap to toolbar")); + TBREPLACEBITMAP replaceBitmap; + replaceBitmap.hInstOld = NULL; + replaceBitmap.hInstNew = NULL; + replaceBitmap.nIDOld = (UINT) oldToolBarBitmap; + replaceBitmap.nIDNew = (UINT) hBitmap; + replaceBitmap.nButtons = nButtons; + if ( !::SendMessage(GetHwnd(), TB_REPLACEBITMAP, + 0, (LPARAM) &replaceBitmap) ) + { + wxFAIL_MSG(wxT("Could not replace the old bitmap")); + } + + ::DeleteObject(oldToolBarBitmap); + + // already done + addBitmap = FALSE; } + else +#endif // TB_REPLACEBITMAP + { + // we can't replace the old bitmap, so we will add another one + // (awfully inefficient, but what else to do?) and shift the bitmap + // indices accordingly + addBitmap = TRUE; - ::DeleteObject(oldToolBarBitmap); + bitmapId = m_nButtons; + } // Now delete all the buttons for ( size_t pos = 0; pos < m_nButtons; pos++ ) @@ -431,8 +449,10 @@ bool wxToolBar::Realize() wxLogLastError("TB_DELETEBUTTON"); } } + } - else // no old bitmap + + if ( addBitmap ) // no old bitmap or we can't replace it { TBADDBITMAP addBitmap; addBitmap.hInst = 0; @@ -453,8 +473,6 @@ bool wxToolBar::Realize() wxArrayInt controlIds; int i = 0; - int bitmapId = 0; - for ( node = m_tools.GetFirst(); node; node = node->GetNext() ) { wxToolBarToolBase *tool = node->GetData(); -- 2.45.2