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