Line data Source code
1 : /* Copyright (C) 2022 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. 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 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #include "precompiled.h"
19 : #include "CmdLineArgs.h"
20 :
21 : #include "lib/sysdep/sysdep.h"
22 :
23 : #include <algorithm>
24 : #include <iterator>
25 : #include <string_view>
26 :
27 1 : CmdLineArgs g_CmdLineArgs;
28 :
29 : namespace
30 : {
31 :
32 : // Simple matcher for elements of the arguments container.
33 265 : class IsKeyEqualTo
34 : {
35 : public:
36 25 : IsKeyEqualTo(const CStr& value) : m_Value(value) {}
37 :
38 51 : bool operator()(const std::pair<CStr, CStr>& p) const
39 : {
40 51 : return p.first == m_Value;
41 : }
42 :
43 : private:
44 : const CStr m_Value;
45 : };
46 :
47 : } // namespace
48 :
49 8 : CmdLineArgs::CmdLineArgs(const PS::span<const char* const> argv)
50 : {
51 8 : if (argv.empty())
52 1 : return;
53 :
54 14 : std::string arg0(argv[0]);
55 : // avoid OsPath complaining about mixing both types of separators,
56 : // which happens when running in the VC2010 debugger
57 7 : std::replace(arg0.begin(), arg0.end(), '/', SYS_DIR_SEP);
58 7 : m_Arg0 = arg0;
59 :
60 : // Implicit conversion from const char* to std::string_view.
61 26 : for (const std::string_view arg : argv.subspan(1))
62 : {
63 : // Only accept arguments that start with '-'
64 24 : if (arg[0] != '-')
65 : {
66 5 : m_ArgsWithoutName.emplace_back(arg);
67 5 : continue;
68 : }
69 :
70 : // Allow -arg and --arg
71 14 : const std::string_view afterDashes = arg.substr(arg[1] == '-' ? 2 : 1);
72 :
73 : // Check for "-arg=value"
74 : const std::string_view::iterator eq =
75 14 : std::find(afterDashes.begin(), afterDashes.end(), '=');
76 :
77 28 : CStr value = (eq != afterDashes.end()) ? CStr{eq + 1, afterDashes.end()} : CStr{};
78 :
79 14 : m_Args.emplace_back(CStr(afterDashes.begin(), eq), std::move(value));
80 : }
81 : }
82 :
83 10 : bool CmdLineArgs::Has(const CStr& name) const
84 : {
85 10 : return std::any_of(m_Args.begin(), m_Args.end(), IsKeyEqualTo(name));
86 : }
87 :
88 8 : CStr CmdLineArgs::Get(const CStr& name) const
89 : {
90 8 : ArgsT::const_iterator it = std::find_if(m_Args.begin(), m_Args.end(), IsKeyEqualTo(name));
91 8 : return it != m_Args.end() ? it->second : "";
92 : }
93 :
94 3 : std::vector<CStr> CmdLineArgs::GetMultiple(const CStr& name) const
95 : {
96 3 : std::vector<CStr> values;
97 3 : ArgsT::const_iterator it = m_Args.begin();
98 11 : while ((it = std::find_if(it, m_Args.end(), IsKeyEqualTo(name))) != m_Args.end())
99 : {
100 4 : values.push_back(it->second);
101 : // Start searching from the next one in the next iteration
102 4 : ++it;
103 : }
104 3 : return values;
105 : }
106 :
107 3 : OsPath CmdLineArgs::GetArg0() const
108 : {
109 3 : return m_Arg0;
110 : }
111 :
112 1 : std::vector<CStr> CmdLineArgs::GetArgsWithoutName() const
113 : {
114 1 : return m_ArgsWithoutName;
115 3 : }
|