The Battle for Wesnoth  1.19.5+dev
commandline_argv.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2020 - 2024
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "commandline_argv.hpp"
16 
17 #ifdef _WIN32
18 
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().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  args.reserve(argc);
89  for(int i = 0; i < argc; ++i) {
90  args.emplace_back(argv[i]);
91  }
92  return args;
93 #endif
94 }
std::vector< std::string > read_argv([[maybe_unused]] int argc, [[maybe_unused]] char **argv)
std::size_t i
Definition: function.cpp:1028
T end(const std::pair< T, T > &p)
EXIT_STATUS start(bool clear_id, const std::string &filename, bool take_screenshot, const std::string &screenshot_filename)
Main interface for launching the editor from the title screen.