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