added wxCmdLineParser::ConvertStringToArgs(), wxApp::ConertToStandardCommandArgs() now uses it

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@12698 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2001-11-25 21:36:28 +00:00
parent a7910d97a3
commit 31f6de22b0
5 changed files with 205 additions and 139 deletions

View File

@ -191,8 +191,11 @@ public:
// gets the value of Nth parameter (as string only for now) // gets the value of Nth parameter (as string only for now)
wxString GetParam(size_t n = 0u) const; wxString GetParam(size_t n = 0u) const;
// Resets switches and options // Resets switches and options
void Reset(); void Reset();
// break down the command line in arguments
static wxArrayString ConvertStringToArgs(const wxChar *cmdline);
private: private:
// common part of all ctors // common part of all ctors
@ -201,6 +204,17 @@ private:
struct wxCmdLineParserData *m_data; struct wxCmdLineParserData *m_data;
}; };
#endif // wxUSE_CMDLINE_PARSER #else // !wxUSE_CMDLINE_PARSER
// this function is always available (even if !wxUSE_CMDLINE_PARSER) because it
// is used by wxWin itself under Windows
class WXDLLEXPORT wxCmdLineParser
{
public:
static wxArrayString ConvertStringToArgs(const wxChar *cmdline);
};
#endif // wxUSE_CMDLINE_PARSER/!wxUSE_CMDLINE_PARSER
#endif // _WX_CMDLINE_H_ #endif // _WX_CMDLINE_H_

View File

@ -81,7 +81,7 @@ public:
static bool UnregisterWindowClasses(); static bool UnregisterWindowClasses();
// Convert Windows to argc, argv style // Convert Windows to argc, argv style
void ConvertToStandardCommandArgs(char* p); void ConvertToStandardCommandArgs(const char* p);
// message processing // message processing
// ------------------ // ------------------

View File

@ -39,42 +39,46 @@
// conditional compilation // conditional compilation
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// what to test (in alphabetic order)? // what to test (in alphabetic order)? uncomment the line below to do all tests
//#define TEST_ALL
//#define TEST_ARRAYS #ifdef TEST_ALL
//#define TEST_CHARSET #define TEST_ARRAYS
//#define TEST_CMDLINE #define TEST_CHARSET
//#define TEST_DATETIME #define TEST_CMDLINE
//#define TEST_DIR #define TEST_DATETIME
//#define TEST_DLLLOADER #define TEST_DIR
//#define TEST_ENVIRON #define TEST_DLLLOADER
//#define TEST_EXECUTE #define TEST_ENVIRON
//#define TEST_FILE #define TEST_EXECUTE
#define TEST_FILECONF #define TEST_FILE
//#define TEST_FILENAME #define TEST_FILECONF
//#define TEST_FILETIME #define TEST_FILENAME
//#define TEST_FTP #define TEST_FILETIME
//#define TEST_HASH #define TEST_FTP
//#define TEST_INFO_FUNCTIONS #define TEST_HASH
//#define TEST_LIST #define TEST_INFO_FUNCTIONS
//#define TEST_LOCALE #define TEST_LIST
//#define TEST_LOG #define TEST_LOCALE
//#define TEST_LONGLONG #define TEST_LOG
//#define TEST_MIME #define TEST_LONGLONG
//#define TEST_PATHLIST #define TEST_MIME
//#define TEST_REGCONF #define TEST_PATHLIST
//#define TEST_REGEX #define TEST_REGCONF
//#define TEST_REGISTRY #define TEST_REGEX
//#define TEST_SNGLINST #define TEST_REGISTRY
//#define TEST_SOCKETS #define TEST_SNGLINST
//#define TEST_STREAMS #define TEST_SOCKETS
//#define TEST_STRINGS #define TEST_STREAMS
//#define TEST_THREADS #define TEST_STRINGS
//#define TEST_TIMER #define TEST_THREADS
//#define TEST_VCARD -- don't enable this (VZ) #define TEST_TIMER
//#define TEST_WCHAR // #define TEST_VCARD -- don't enable this (VZ)
//#define TEST_ZIP #define TEST_WCHAR
//#define TEST_ZLIB #define TEST_ZIP
#define TEST_ZLIB
#else
#define TEST_CMDLINE
#endif
#ifdef TEST_SNGLINST #ifdef TEST_SNGLINST
#include "wx/snglinst.h" #include "wx/snglinst.h"
@ -178,6 +182,8 @@ static void TestCharset()
#include "wx/cmdline.h" #include "wx/cmdline.h"
#include "wx/datetime.h" #include "wx/datetime.h"
#if wxUSE_CMDLINE_PARSER
static void ShowCmdLine(const wxCmdLineParser& parser) static void ShowCmdLine(const wxCmdLineParser& parser)
{ {
wxString s = "Input files: "; wxString s = "Input files: ";
@ -209,6 +215,32 @@ static void ShowCmdLine(const wxCmdLineParser& parser)
wxLogMessage(s); wxLogMessage(s);
} }
#endif // wxUSE_CMDLINE_PARSER
static void TestCmdLineConvert()
{
static const char *cmdlines[] =
{
"arg1 arg2",
"-a \"-bstring 1\" -c\"string 2\" \"string 3\"",
"literal \\\" and \"\"",
};
for ( size_t n = 0; n < WXSIZEOF(cmdlines); n++ )
{
const char *cmdline = cmdlines[n];
printf("Parsing: %s\n", cmdline);
wxArrayString args = wxCmdLineParser::ConvertStringToArgs(cmdline);
size_t count = args.GetCount();
printf("\targc = %u\n", count);
for ( size_t arg = 0; arg < count; arg++ )
{
printf("\targv[%u] = %s\n", arg, args[arg]);
}
}
}
#endif // TEST_CMDLINE #endif // TEST_CMDLINE
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -4944,6 +4976,9 @@ int main(int argc, char **argv)
#endif // TEST_CHARSET #endif // TEST_CHARSET
#ifdef TEST_CMDLINE #ifdef TEST_CMDLINE
TestCmdLineConvert();
#if wxUSE_CMDLINE_PARSER
static const wxCmdLineEntryDesc cmdLineDesc[] = static const wxCmdLineEntryDesc cmdLineDesc[] =
{ {
{ wxCMD_LINE_SWITCH, _T("h"), _T("help"), "show this help message", { wxCMD_LINE_SWITCH, _T("h"), _T("help"), "show this help message",
@ -4984,6 +5019,8 @@ int main(int argc, char **argv)
wxLogMessage("Syntax error detected, aborting."); wxLogMessage("Syntax error detected, aborting.");
break; break;
} }
#endif // wxUSE_CMDLINE_PARSER
#endif // TEST_CMDLINE #endif // TEST_CMDLINE
#ifdef TEST_STRINGS #ifdef TEST_STRINGS

View File

@ -28,6 +28,8 @@
#pragma hdrstop #pragma hdrstop
#endif #endif
#include "wx/cmdline.h"
#if wxUSE_CMDLINE_PARSER #if wxUSE_CMDLINE_PARSER
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
@ -42,7 +44,6 @@
#include <ctype.h> #include <ctype.h>
#include "wx/datetime.h" #include "wx/datetime.h"
#include "wx/cmdline.h"
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// private functions // private functions
@ -201,44 +202,9 @@ void wxCmdLineParserData::SetArguments(const wxString& cmdLine)
m_arguments.Add(wxTheApp->GetAppName()); m_arguments.Add(wxTheApp->GetAppName());
// Break up string wxArrayString args = wxCmdLineParser::ConvertStringToArgs(cmdLine);
// Treat strings enclosed in double-quotes as single arguments
int i = 0;
int len = cmdLine.Length();
while (i < len)
{
// Skip whitespace
while ((i < len) && wxIsspace(cmdLine.GetChar(i)))
i ++;
if (i < len) WX_APPEND_ARRAY(m_arguments, args);
{
if (cmdLine.GetChar(i) == wxT('"')) // We found the start of a string
{
i ++;
int first = i;
while ((i < len) && (cmdLine.GetChar(i) != wxT('"')))
i ++;
wxString arg(cmdLine.Mid(first, (i - first)));
m_arguments.Add(arg);
if (i < len)
i ++; // Skip past 2nd quote
}
else // Unquoted argument
{
int first = i;
while ((i < len) && !wxIsspace(cmdLine.GetChar(i)))
i ++;
wxString arg(cmdLine.Mid(first, (i - first)));
m_arguments.Add(arg);
}
}
}
} }
int wxCmdLineParserData::FindOption(const wxString& name) int wxCmdLineParserData::FindOption(const wxString& name)
@ -964,7 +930,7 @@ void wxCmdLineParser::Usage()
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// global functions // private functions
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
static wxString GetTypeName(wxCmdLineParamType type) static wxString GetTypeName(wxCmdLineParamType type)
@ -985,3 +951,96 @@ static wxString GetTypeName(wxCmdLineParamType type)
} }
#endif // wxUSE_CMDLINE_PARSER #endif // wxUSE_CMDLINE_PARSER
// ----------------------------------------------------------------------------
// global functions
// ----------------------------------------------------------------------------
/* static */
wxArrayString wxCmdLineParser::ConvertStringToArgs(const wxChar *p)
{
wxArrayString args;
wxString arg;
arg.reserve(1024);
bool isInsideQuotes = FALSE;
for ( ;; )
{
// skip white space
while ( *p == _T(' ') || *p == _T('\t') )
p++;
// anything left?
if ( *p == _T('\0') )
break;
// parse this parameter
arg.clear();
for ( ;; p++ )
{
// do we have a (lone) backslash?
bool isQuotedByBS = FALSE;
while ( *p == _T('\\') )
{
p++;
// if we have 2 backslashes in a row, output one
if ( isQuotedByBS )
{
arg += _T('\\');
isQuotedByBS = FALSE;
}
else // the next char is quoted
{
isQuotedByBS = TRUE;
}
}
bool skipChar = FALSE,
endParam = FALSE;
switch ( *p )
{
case _T('"'):
if ( !isQuotedByBS )
{
// don't put the quote itself in the arg
skipChar = TRUE;
isInsideQuotes = !isInsideQuotes;
}
//else: insert a literal quote
break;
case _T(' '):
case _T('\t'):
if ( isInsideQuotes )
{
// preserve it, skip endParam below
break;
}
//else: fall through
case _T('\0'):
endParam = TRUE;
break;
}
// end of argument?
if ( endParam )
break;
// otherwise copy this char to arg
if ( !skipChar )
{
arg += *p;
}
}
args.Add(arg);
}
return args;
}

View File

@ -45,9 +45,10 @@
#include "wx/dynarray.h" #include "wx/dynarray.h"
#include "wx/wxchar.h" #include "wx/wxchar.h"
#include "wx/icon.h" #include "wx/icon.h"
#include "wx/log.h"
#endif #endif
#include "wx/log.h" #include "wx/cmdline.h"
#include "wx/module.h" #include "wx/module.h"
#include "wx/msw/private.h" #include "wx/msw/private.h"
@ -548,73 +549,28 @@ bool wxApp::UnregisterWindowClasses()
// Convert Windows to argc, argv style // Convert Windows to argc, argv style
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
void wxApp::ConvertToStandardCommandArgs(char* lpCmdLine) void wxApp::ConvertToStandardCommandArgs(const char* lpCmdLine)
{ {
wxStringList args; // break the command line in words
wxArrayString args =
wxCmdLineParser::ConvertStringToArgs(wxConvertMB2WX(lpCmdLine));
wxString cmdLine(lpCmdLine); // +1 here for the program name
int count = 0; argc = args.GetCount() + 1;
// Get application name // and +1 here for the terminating NULL
wxChar name[260]; // 260 is MAX_PATH value from windef.h argv = new wxChar *[argc + 1];
::GetModuleFileName(wxhInstance, name, WXSIZEOF(name));
args.Add(name); argv[0] = new wxChar[260]; // 260 is MAX_PATH value from windef.h
count++; ::GetModuleFileName(wxhInstance, argv[0], 260);
wxStrcpy(name, wxFileNameFromPath(name)); for ( int i = 1; i < argc; i++ )
wxStripExtension(name);
wxTheApp->SetAppName(name);
// Break up string
// Treat strings enclosed in double-quotes as single arguments
int i = 0;
int len = cmdLine.Length();
while (i < len)
{ {
// Skip whitespace argv[i] = copystring(args[i - 1]);
while ((i < len) && wxIsspace(cmdLine.GetChar(i)))
i ++;
if (i < len)
{
if (cmdLine.GetChar(i) == wxT('"')) // We found the start of a string
{
i ++;
int first = i;
while ((i < len) && (cmdLine.GetChar(i) != wxT('"')))
i ++;
wxString arg(cmdLine.Mid(first, (i - first)));
args.Add(arg);
count ++;
if (i < len)
i ++; // Skip past 2nd quote
}
else // Unquoted argument
{
int first = i;
while ((i < len) && !wxIsspace(cmdLine.GetChar(i)))
i ++;
wxString arg(cmdLine.Mid(first, (i - first)));
args.Add(arg);
count ++;
}
}
} }
wxTheApp->argv = new wxChar*[count + 1]; // argv[] must be NULL-terminated
for (i = 0; i < count; i++) argv[argc] = NULL;
{
wxString arg(args[i]);
wxTheApp->argv[i] = copystring((const wxChar*)arg);
}
wxTheApp->argv[count] = NULL; // argv[] is a NULL-terminated list
wxTheApp->argc = count;
} }
//// Cleans up any wxWindows internal structures left lying around //// Cleans up any wxWindows internal structures left lying around