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: CmdLineArgs()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 CmdLineArgs(const int argc,const char ** argv)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 ~CmdLineArgs()81 ~CmdLineArgs() 82 { 83 delete[] m_cmdline; 84 } 85 86 private: 87 char* m_cmdline; // the command line string 88 89 //////////////////////////////////////////////////////////////////////////////// 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 96 //////////////////////////////////////////////////////////////////////////////// ParseCmdLine()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 149