1 // TortoiseSVN - a Windows shell extension for easy version control
\r
3 // Copyright (C) 2003-2006 - Stefan Kueng
\r
5 // This program is free software; you can redistribute it and/or
\r
6 // modify it under the terms of the GNU General Public License
\r
7 // as published by the Free Software Foundation; either version 2
\r
8 // of the License, or (at your option) any later version.
\r
10 // This program is distributed in the hope that it will be useful,
\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 // GNU General Public License for more details.
\r
15 // You should have received a copy of the GNU General Public License
\r
16 // along with this program; if not, write to the Free Software Foundation,
\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
20 #include "CmdLineParser.h"
\r
22 #include <algorithm>
\r
24 const TCHAR CCmdLineParser::m_sDelims[] = _T("-/");
\r
25 const TCHAR CCmdLineParser::m_sQuotes[] = _T("\"");
\r
26 const TCHAR CCmdLineParser::m_sValueSep[] = _T(" :"); // don't forget space!!
\r
29 CCmdLineParser::CCmdLineParser(LPCTSTR sCmdLine)
\r
37 CCmdLineParser::~CCmdLineParser()
\r
42 BOOL CCmdLineParser::Parse(LPCTSTR sCmdLine)
\r
44 const stdstring sEmpty = _T(""); //use this as a value if no actual value is given in commandline
\r
51 m_sCmdLine = sCmdLine;
\r
53 LPCTSTR sCurrent = sCmdLine;
\r
57 //format is -Key:"arg"
\r
59 if (_tcslen(sCurrent) == 0)
\r
60 break; // no more data, leave loop
\r
62 LPCTSTR sArg = _tcspbrk(sCurrent, m_sDelims);
\r
64 break; // no (more) delimiters found
\r
65 sArg = _tcsinc(sArg);
\r
67 if(_tcslen(sArg) == 0)
\r
68 break; // ends with delim
\r
70 LPCTSTR sVal = _tcspbrk(sArg, m_sValueSep);
\r
73 stdstring Key(sArg);
\r
74 std::transform(Key.begin(), Key.end(), Key.begin(), ::tolower);
\r
75 m_valueMap.insert(CValsMap::value_type(Key, sEmpty));
\r
78 else if (sVal[0] == _T(' ') || _tcslen(sVal) == 1 )
\r
80 // cmdline ends with /Key: or a key with no value
\r
81 stdstring Key(sArg, (int)(sVal - sArg));
\r
84 std::transform(Key.begin(), Key.end(), Key.begin(), ::tolower);
\r
85 m_valueMap.insert(CValsMap::value_type(Key, sEmpty));
\r
87 sCurrent = _tcsinc(sVal);
\r
93 stdstring Key(sArg, (int)(sVal - sArg));
\r
94 std::transform(Key.begin(), Key.end(), Key.begin(), ::tolower);
\r
96 sVal = _tcsinc(sVal);
\r
98 LPCTSTR sQuote = _tcspbrk(sVal, m_sQuotes), sEndQuote(NULL);
\r
101 // string with quotes (defined in m_sQuotes, e.g. '")
\r
102 sQuote = _tcsinc(sVal);
\r
103 sEndQuote = _tcspbrk(sQuote, m_sQuotes);
\r
108 sEndQuote = _tcschr(sQuote, _T(' '));
\r
111 if(sEndQuote == NULL)
\r
113 // no end quotes or terminating space, take the rest of the string to its end
\r
114 stdstring csVal(sQuote);
\r
117 m_valueMap.insert(CValsMap::value_type(Key, csVal));
\r
126 stdstring csVal(sQuote, (int)(sEndQuote - sQuote));
\r
127 m_valueMap.insert(CValsMap::value_type(Key, csVal));
\r
129 sCurrent = _tcsinc(sEndQuote);
\r
135 return (nArgs > 0); //TRUE if arguments were found
\r
138 CCmdLineParser::CValsMap::const_iterator CCmdLineParser::findKey(LPCTSTR sKey) const
\r
141 std::transform(s.begin(), s.end(), s.begin(), ::tolower);
\r
142 return m_valueMap.find(s);
\r
145 BOOL CCmdLineParser::HasKey(LPCTSTR sKey) const
\r
147 CValsMap::const_iterator it = findKey(sKey);
\r
148 if(it == m_valueMap.end())
\r
154 BOOL CCmdLineParser::HasVal(LPCTSTR sKey) const
\r
156 CValsMap::const_iterator it = findKey(sKey);
\r
157 if(it == m_valueMap.end())
\r
159 if(it->second.empty())
\r
164 LPCTSTR CCmdLineParser::GetVal(LPCTSTR sKey) const
\r
166 CValsMap::const_iterator it = findKey(sKey);
\r
167 if (it == m_valueMap.end())
\r
169 return it->second.c_str();
\r
172 LONG CCmdLineParser::GetLongVal(LPCTSTR sKey) const
\r
174 CValsMap::const_iterator it = findKey(sKey);
\r
175 if (it == m_valueMap.end())
\r
177 return _tstol(it->second.c_str());
\r
181 CCmdLineParser::ITERPOS CCmdLineParser::begin() const
\r
183 return m_valueMap.begin();
\r
186 CCmdLineParser::ITERPOS CCmdLineParser::getNext(ITERPOS& pos, stdstring& sKey, stdstring& sValue) const
\r
188 if (m_valueMap.end() == pos)
\r
196 sValue = pos->second;
\r
202 BOOL CCmdLineParser::isLast(const ITERPOS& pos) const
\r
204 return (pos == m_valueMap.end());
\r