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
|
/*
* Copyright (C) 2005-2013 Team XBMC
* http://kodi.tv
*
* 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, see
* <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#ifdef TARGET_POSIX
char* GetCommandLine();
#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.
char* cmdline = GetCommandLine();
m_cmdline = new char [strlen (cmdline) + 1];
if (m_cmdline)
{
strcpy (m_cmdline, cmdline);
ParseCmdLine();
} else {
#ifdef TARGET_POSIX
delete[] cmdline;
#endif
}
}
CmdLineArgs (const int argc, const char **argv)
{
std::string cmdline;
#ifdef TARGET_POSIX
cmdline = "\"";
#endif
for (int i = 0 ; i<argc ; i++)
{
cmdline += std::string(argv[i]);
if ( i != (argc-1) )
{
#ifdef TARGET_POSIX
cmdline += "\" \"";
#else
cmdline += " ";
#endif
}
}
#ifdef TARGET_POSIX
cmdline += "\"";
#endif
m_cmdline = new char [cmdline.length() + 1];
if (m_cmdline)
{
strcpy(m_cmdline, cmdline.c_str());
ParseCmdLine();
}
}
~CmdLineArgs()
{
delete[] m_cmdline;
}
private:
char* 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;
char* 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
|