1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
#ifndef CMDLINEARGS_H
#define CMDLINEARGS_H
/*
* Copyright (C) 2005-2010 Team XBMC
* http://www.xbmc.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with XBMC; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#ifdef _LINUX
#include "PlatformDefs.h"
#include "xwinapi.h"
typedef LPSTR PSZ;
#define _snprintf snprintf
#else
#include <windows.h>
#endif
#include <vector>
#include <string>
class CmdLineArgs : public std::vector<char*>
{
public:
CmdLineArgs ()
{
// Save local copy of the command line string, because
// ParseCmdLine() modifies this string while parsing it.
PSZ cmdline = GetCommandLine();
m_cmdline = new char [strlen (cmdline) + 1];
if (m_cmdline)
{
strcpy (m_cmdline, cmdline);
ParseCmdLine();
} else {
#ifdef _LINUX
delete[] cmdline;
#endif
}
}
CmdLineArgs (const int argc, const char **argv)
{
std::string cmdline;
#ifdef _LINUX
cmdline = "\"";
#endif
for (int i = 0 ; i<argc ; i++)
{
cmdline += std::string(argv[i]);
if ( i != (argc-1) )
{
#ifdef _LINUX
cmdline += "\" \"";
#else
cmdline += " ";
#endif
}
}
#ifdef _LINUX
cmdline += "\"";
#endif
m_cmdline = new char [cmdline.length() + 1];
if (m_cmdline)
{
strcpy(m_cmdline, cmdline.c_str());
ParseCmdLine();
}
}
~CmdLineArgs()
{
delete[] m_cmdline;
}
private:
PSZ m_cmdline; // the command line string
////////////////////////////////////////////////////////////////////////////////
// Parse m_cmdline into individual tokens, which are delimited by spaces. If a
// token begins with a quote, then that token is terminated by the next quote
// followed immediately by a space or terminator. This allows tokens to contain
// spaces.
// This input string: This "is" a ""test"" "of the parsing" alg"o"rithm.
// Produces these tokens: This, is, a, "test", of the parsing, alg"o"rithm
////////////////////////////////////////////////////////////////////////////////
void ParseCmdLine ()
{
enum { TERM = '\0',
QUOTE = '\"' };
bool bInQuotes = false;
PSZ pargs = m_cmdline;
while (*pargs)
{
while (isspace (*pargs)) // skip leading whitespace
pargs++;
bInQuotes = (*pargs == QUOTE); // see if this token is quoted
if (bInQuotes) // skip leading quote
pargs++;
push_back (pargs); // store position of current token
// Find next token.
// NOTE: Args are normally terminated by whitespace, unless the
// arg is quoted. That's why we handle the two cases separately,
// even though they are very similar.
if (bInQuotes)
{
// find next quote followed by a space or terminator
while (*pargs &&
!(*pargs == QUOTE && (isspace (pargs[1]) || pargs[1] == TERM)))
pargs++;
if (*pargs)
{
*pargs = TERM; // terminate token
if (pargs[1]) // if quoted token not followed by a terminator
pargs += 2; // advance to next token
}
}
else
{
// skip to next non-whitespace character
while (*pargs && !isspace (*pargs))
pargs++;
if (*pargs && isspace (*pargs)) // end of token
{
*pargs = TERM; // terminate token
pargs++; // advance to next token or terminator
}
}
} // while (*pargs)
} // ParseCmdLine()
}; // class CmdLineArgs
#endif // CMDLINEARGS_H
|