The Battle for Wesnoth  1.15.9+dev
commandline_argv.cpp
Go to the documentation of this file.
1 /*
2  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY.
10 
11  See the COPYING file for more details.
12 */
13 
14 #include "commandline_argv.hpp"
15 
16 #ifdef _WIN32
17 
18 #include "global.hpp"
20 
21 #include <windows.h>
22 
23 namespace {
24 
25 bool win32_parse_single_arg(const char*& next, const char* end, std::string& res)
26 {
27  // strip leading whitespace
28  while(next != end && *next == ' ') {
29  ++next;
30  }
31 
32  if(next == end) {
33  return false;
34  }
35 
36  bool is_escaped = false;
37 
38  for(; next != end; ++next) {
39  if(*next == ' ' && !is_escaped) {
40  break;
41  } else if(*next == '"' && !is_escaped) {
42  is_escaped = true;
43  continue;
44  } else if(*next == '"' && is_escaped && next + 1 != end && *(next + 1) == '"') {
45  res.push_back('"');
46  ++next;
47  continue;
48  } else if(*next == '"' && is_escaped) {
49  is_escaped = false;
50  continue;
51  } else {
52  res.push_back(*next);
53  }
54  }
55 
56  return true;
57 }
58 
59 std::vector<std::string> win32_read_argv(const std::string& input)
60 {
61  const char* start = &input[0];
62  const char* end = start + input.size();
63 
64  std::string buffer;
65  std::vector<std::string> res;
66 
67  while(win32_parse_single_arg(start, end, buffer)) {
68  res.emplace_back();
69  res.back().swap(buffer);
70  }
71 
72  return res;
73 }
74 
75 }
76 
77 #endif
78 
79 std::vector<std::string> read_argv(int argc, char** argv)
80 {
81 #ifdef _WIN32
82  UNUSED(argc);
83  UNUSED(argv);
84  // On Windows, argv is ANSI-encoded by default. Wesnoth absolutely needs to
85  // work with UTF-8 values in order to avoid losing or corrupting
86  // information from the command line.
87  auto flat_cmdline = unicode_cast<std::string>(std::wstring{GetCommandLineW()});
88  return win32_read_argv(flat_cmdline);
89 #else
90  std::vector<std::string> args;
91  for(int i = 0; i < argc; ++i) {
92  args.push_back(std::string(argv[i]));
93  }
94  return args;
95 #endif
96 }
ucs4_convert_impl::enableif< TD, typename TS::value_type >::type unicode_cast(const TS &source)
std::vector< std::string > read_argv(int argc, char **argv)
Reads argv into a vector of STL strings.
#define UNUSED(x)
Definition: global.hpp:40
std::size_t i
Definition: function.cpp:933
#define next(ls)
Definition: llex.cpp:32
EXIT_STATUS start(const std::string &filename, bool take_screenshot, const std::string &screenshot_filename)
Main interface for launching the editor from the title screen.
Definition: editor_main.cpp:28