The Battle for Wesnoth  1.17.0-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 
19 
20 #include <windows.h>
21 
22 namespace {
23 
24 bool win32_parse_single_arg(const char*& next, const char* end, std::string& res)
25 {
26  // strip leading whitespace
27  while(next != end && *next == ' ') {
28  ++next;
29  }
30 
31  if(next == end) {
32  return false;
33  }
34 
35  bool is_escaped = false;
36 
37  for(; next != end; ++next) {
38  if(*next == ' ' && !is_escaped) {
39  break;
40  } else if(*next == '"' && !is_escaped) {
41  is_escaped = true;
42  continue;
43  } else if(*next == '"' && is_escaped && next + 1 != end && *(next + 1) == '"') {
44  res.push_back('"');
45  ++next;
46  continue;
47  } else if(*next == '"' && is_escaped) {
48  is_escaped = false;
49  continue;
50  } else {
51  res.push_back(*next);
52  }
53  }
54 
55  return true;
56 }
57 
58 std::vector<std::string> win32_read_argv(const std::string& input)
59 {
60  const char* start = &input[0];
61  const char* end = start + input.size();
62 
63  std::string buffer;
64  std::vector<std::string> res;
65 
66  while(win32_parse_single_arg(start, end, buffer)) {
67  res.emplace_back();
68  res.back().swap(buffer);
69  }
70 
71  return res;
72 }
73 
74 }
75 
76 #endif
77 
78 std::vector<std::string> read_argv([[maybe_unused]] int argc, [[maybe_unused]] char** argv)
79 {
80 #ifdef _WIN32
81  // On Windows, argv is ANSI-encoded by default. Wesnoth absolutely needs to
82  // work with UTF-8 values in order to avoid losing or corrupting
83  // information from the command line.
84  auto flat_cmdline = unicode_cast<std::string>(std::wstring{GetCommandLineW()});
85  return win32_read_argv(flat_cmdline);
86 #else
87  std::vector<std::string> args;
88  for(int i = 0; i < argc; ++i) {
89  args.push_back(std::string(argv[i]));
90  }
91  return args;
92 #endif
93 }
ucs4_convert_impl::enableif< TD, typename TS::value_type >::type unicode_cast(const TS &source)
std::size_t i
Definition: function.cpp:940
#define next(ls)
Definition: llex.cpp:32
std::vector< std::string > read_argv([[maybe_unused]] int argc, [[maybe_unused]] char **argv)
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