Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: base/command_line.cc

Issue 7249: Store the command line in a more convenient format on non-windows platforms. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/command_line.h" 5 #include "base/command_line.h"
6 6
7 #if defined(OS_WIN) 7 #if defined(OS_WIN)
8 #include <windows.h> 8 #include <windows.h>
9 #include <shellapi.h> 9 #include <shellapi.h>
10 #endif 10 #endif
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 // accessing this object on multiple threads. To ensure thread safety, the 50 // accessing this object on multiple threads. To ensure thread safety, the
51 // public interface of this object is const only. 51 // public interface of this object is const only.
52 // 52 //
53 // Do NOT add any non-const methods to this object. You have been warned. 53 // Do NOT add any non-const methods to this object. You have been warned.
54 class CommandLine::Data { 54 class CommandLine::Data {
55 public: 55 public:
56 #if defined(OS_WIN) 56 #if defined(OS_WIN)
57 Data() { 57 Data() {
58 Init(GetCommandLineW()); 58 Init(GetCommandLineW());
59 } 59 }
60
61 Data(const wstring& command_line) {
62 Init(command_line);
63 }
60 #elif defined(OS_POSIX) 64 #elif defined(OS_POSIX)
61 Data() { 65 Data() {
62 // Owner must call Init(). 66 // Owner must call Init().
63 } 67 }
64 #endif
65 68
66 #if defined(OS_WIN)
67 Data(const wstring& command_line) {
68 Init(command_line);
69 }
70 #elif defined(OS_POSIX)
71 Data(int argc, const char* const* argv) { 69 Data(int argc, const char* const* argv) {
72 Init(argc, argv); 70 Init(argc, argv);
73 } 71 }
74 #endif 72 #endif // defined(OS_POSIX)
75 73
76 #if defined(OS_WIN) 74 #if defined(OS_WIN)
77 // Does the actual parsing of the command line. 75 // Does the actual parsing of the command line.
78 void Init(const std::wstring& command_line) { 76 void Init(const std::wstring& command_line) {
79 TrimWhitespace(command_line, TRIM_ALL, &command_line_string_); 77 TrimWhitespace(command_line, TRIM_ALL, &command_line_string_);
80 78
81 if (command_line_string_.empty()) 79 if (command_line_string_.empty())
82 return; 80 return;
83 81
84 int num_args = 0; 82 int num_args = 0;
(...skipping 24 matching lines...) Expand all
109 if (IsSwitch(arg, &switch_string, &switch_value)) { 107 if (IsSwitch(arg, &switch_string, &switch_value)) {
110 switches_[switch_string] = switch_value; 108 switches_[switch_string] = switch_value;
111 } else { 109 } else {
112 loose_values_.push_back(arg); 110 loose_values_.push_back(arg);
113 } 111 }
114 } 112 }
115 113
116 if (args) 114 if (args)
117 LocalFree(args); 115 LocalFree(args);
118 } 116 }
119
120 #elif defined(OS_POSIX) 117 #elif defined(OS_POSIX)
121 // Does the actual parsing of the command line. 118 // Does the actual parsing of the command line.
122 void Init(int argc, const char* const* argv) { 119 void Init(int argc, const char* const* argv) {
123 if (argc < 1) 120 if (argc < 1)
124 return; 121 return;
125 program_ = base::SysNativeMBToWide(argv[0]); 122 program_ = base::SysNativeMBToWide(argv[0]);
123 argv_.push_back(std::string(argv[0]));
126 command_line_string_ = program_; 124 command_line_string_ = program_;
127 125
128 bool parse_switches = true; 126 bool parse_switches = true;
129 for (int i = 1; i < argc; ++i) { 127 for (int i = 1; i < argc; ++i) {
130 std::wstring arg = base::SysNativeMBToWide(argv[i]); 128 std::wstring arg = base::SysNativeMBToWide(argv[i]);
129 argv_.push_back(argv[i]);
131 command_line_string_.append(L" "); 130 command_line_string_.append(L" ");
132 command_line_string_.append(arg); 131 command_line_string_.append(arg);
133 132
134 if (!parse_switches) { 133 if (!parse_switches) {
135 loose_values_.push_back(arg); 134 loose_values_.push_back(arg);
136 continue; 135 continue;
137 } 136 }
138 137
139 if (arg == kSwitchTerminator) { 138 if (arg == kSwitchTerminator) {
140 parse_switches = false; 139 parse_switches = false;
(...skipping 20 matching lines...) Expand all
161 } 160 }
162 161
163 const std::map<std::wstring, std::wstring>& switches() const { 162 const std::map<std::wstring, std::wstring>& switches() const {
164 return switches_; 163 return switches_;
165 } 164 }
166 165
167 const std::vector<std::wstring>& loose_values() const { 166 const std::vector<std::wstring>& loose_values() const {
168 return loose_values_; 167 return loose_values_;
169 } 168 }
170 169
170 #if defined(OS_POSIX)
171 const std::vector<std::string>& argv() const {
172 return argv_;
173 }
174 #endif
175
171 private: 176 private:
172 // Returns true if parameter_string represents a switch. If true, 177 // Returns true if parameter_string represents a switch. If true,
173 // switch_string and switch_value are set. (If false, both are 178 // switch_string and switch_value are set. (If false, both are
174 // set to the empty string.) 179 // set to the empty string.)
175 static bool IsSwitch(const wstring& parameter_string, 180 static bool IsSwitch(const wstring& parameter_string,
176 wstring* switch_string, 181 wstring* switch_string,
177 wstring* switch_value) { 182 wstring* switch_value) {
178 183
179 *switch_string = L""; 184 *switch_string = L"";
180 *switch_value = L""; 185 *switch_value = L"";
(...skipping 18 matching lines...) Expand all
199 return true; 204 return true;
200 } 205 }
201 206
202 return false; 207 return false;
203 } 208 }
204 209
205 std::wstring command_line_string_; 210 std::wstring command_line_string_;
206 std::wstring program_; 211 std::wstring program_;
207 std::map<std::wstring, std::wstring> switches_; 212 std::map<std::wstring, std::wstring> switches_;
208 std::vector<std::wstring> loose_values_; 213 std::vector<std::wstring> loose_values_;
214 std::vector<std::string> argv_;
209 215
210 DISALLOW_EVIL_CONSTRUCTORS(Data); 216 DISALLOW_EVIL_CONSTRUCTORS(Data);
211 }; 217 };
212 218
213 CommandLine::CommandLine() 219 CommandLine::CommandLine()
214 : we_own_data_(false), // The Singleton class will manage it for us. 220 : we_own_data_(false), // The Singleton class will manage it for us.
215 data_(Singleton<Data>::get()) { 221 data_(Singleton<Data>::get()) {
216 DCHECK(!data_->command_line_string().empty()) << 222 DCHECK(!data_->command_line_string().empty()) <<
217 "You must call CommandLine::SetArgcArgv before making any CommandLine " 223 "You must call CommandLine::SetArgcArgv before making any CommandLine "
218 "calls."; 224 "calls.";
219 } 225 }
220 226
221 #if defined(OS_WIN) 227 #if defined(OS_WIN)
222 CommandLine::CommandLine(const wstring& command_line) 228 CommandLine::CommandLine(const wstring& command_line)
223 : we_own_data_(true), 229 : we_own_data_(true),
224 data_(new Data(command_line)) { 230 data_(new Data(command_line)) {
225 } 231 }
226 #elif defined(OS_POSIX) 232 #elif defined(OS_POSIX)
227 CommandLine::CommandLine(const int argc, const char* const* argv) 233 CommandLine::CommandLine(const int argc, const char* const* argv)
228 : we_own_data_(true), 234 : we_own_data_(true),
229 data_(new Data(argc, argv)) { 235 data_(new Data(argc, argv)) {
230 } 236 }
237
238 CommandLine::CommandLine(const std::vector<std::string>& argv)
239 : we_own_data_(true) {
240 const char* argv_copy[argv.size()];
241 for (size_t i = 0; i < argv.size(); i++) {
242 argv_copy[i] = argv[i].c_str();
243 }
244 data_ = new Data(argv.size(), argv_copy);
245 }
231 #endif 246 #endif
232 247
233 CommandLine::~CommandLine() { 248 CommandLine::~CommandLine() {
234 if (we_own_data_) 249 if (we_own_data_)
235 delete data_; 250 delete data_;
236 } 251 }
237 252
238 // static 253 // static
239 void CommandLine::SetArgcArgv(int argc, const char* const* argv) { 254 void CommandLine::SetArgcArgv(int argc, const char* const* argv) {
240 #if !defined(OS_WIN) 255 #if !defined(OS_WIN)
(...skipping 30 matching lines...) Expand all
271 } 286 }
272 287
273 CommandLine::LooseValueIterator CommandLine::GetLooseValuesEnd() const { 288 CommandLine::LooseValueIterator CommandLine::GetLooseValuesEnd() const {
274 return data_->loose_values().end(); 289 return data_->loose_values().end();
275 } 290 }
276 291
277 std::wstring CommandLine::command_line_string() const { 292 std::wstring CommandLine::command_line_string() const {
278 return data_->command_line_string(); 293 return data_->command_line_string();
279 } 294 }
280 295
296 #if defined(OS_POSIX)
297 const std::vector<std::string>& CommandLine::argv() const {
298 return data_->argv();
299 }
300 #endif
301
281 std::wstring CommandLine::program() const { 302 std::wstring CommandLine::program() const {
282 return data_->program(); 303 return data_->program();
283 } 304 }
284 305
285 // static 306 // static
307 wstring CommandLine::PrefixedSwitchString(const wstring& switch_string) {
308 return StringPrintf(L"%ls%ls",
309 kSwitchPrefixes[0],
310 switch_string.c_str());
311 }
312
313 // static
314 wstring CommandLine::PrefixedSwitchStringWithValue(
315 const wstring& switch_string, const wstring& value_string) {
316 if (value_string.empty()) {
317 return PrefixedSwitchString(switch_string);
318 }
319
320 return StringPrintf(L"%ls%ls%ls%ls",
321 kSwitchPrefixes[0],
322 switch_string.c_str(),
323 kSwitchValueSeparator,
324 value_string.c_str());
325 }
326
327 // static
286 void CommandLine::AppendSwitch(wstring* command_line_string, 328 void CommandLine::AppendSwitch(wstring* command_line_string,
287 const wstring& switch_string) { 329 const wstring& switch_string) {
288 DCHECK(command_line_string); 330 DCHECK(command_line_string);
331 wstring prefixed_switch_string = PrefixedSwitchString(switch_string);
289 command_line_string->append(L" "); 332 command_line_string->append(L" ");
290 command_line_string->append(kSwitchPrefixes[0]); 333 command_line_string->append(prefixed_switch_string);
291 command_line_string->append(switch_string);
292 } 334 }
293 335
294 // static 336 // static
295 void CommandLine::AppendSwitchWithValue(wstring* command_line_string, 337 void CommandLine::AppendSwitchWithValue(wstring* command_line_string,
296 const wstring& switch_string, 338 const wstring& switch_string,
297 const wstring& value_string) { 339 const wstring& value_string) {
298 AppendSwitch(command_line_string, switch_string); 340 wstring value_string_edit;
299 341
300 if (value_string.empty())
301 return;
302
303 command_line_string->append(kSwitchValueSeparator);
304 // NOTE(jhughes): If the value contains a quotation mark at one 342 // NOTE(jhughes): If the value contains a quotation mark at one
305 // end but not both, you may get unusable output. 343 // end but not both, you may get unusable output.
306 if ((value_string.find(L" ") != std::wstring::npos) && 344 if (!value_string.empty() &&
345 (value_string.find(L" ") != std::wstring::npos) &&
307 (value_string[0] != L'"') && 346 (value_string[0] != L'"') &&
308 (value_string[value_string.length() - 1] != L'"')) { 347 (value_string[value_string.length() - 1] != L'"')) {
309 // need to provide quotes 348 // need to provide quotes
310 StringAppendF(command_line_string, L"\"%ls\"", value_string.c_str()); 349 value_string_edit = StringPrintf(L"\"%ls\"", value_string.c_str());
311 } else { 350 } else {
312 command_line_string->append(value_string); 351 value_string_edit = value_string;
313 } 352 }
353
354 wstring combined_switch_string =
355 PrefixedSwitchStringWithValue(switch_string, value_string_edit);
356
357 command_line_string->append(L" ");
358 command_line_string->append(combined_switch_string);
314 } 359 }
315 360
OLDNEW
« base/command_line.h ('K') | « base/command_line.h ('k') | base/command_line_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698