4624f1c0a0db3a70fdc47859b78c816e6696a0f9
[platform/upstream/cmake.git] / Source / cmArgumentParser.cxx
1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt or https://cmake.org/licensing for details.  */
3 #include "cmArgumentParser.h"
4
5 #include <algorithm>
6
7 namespace ArgumentParser {
8
9 auto ActionMap::Emplace(cm::string_view name, Action action)
10   -> std::pair<iterator, bool>
11 {
12   auto const it =
13     std::lower_bound(this->begin(), this->end(), name,
14                      [](value_type const& elem, cm::string_view const& k) {
15                        return elem.first < k;
16                      });
17   return (it != this->end() && it->first == name)
18     ? std::make_pair(it, false)
19     : std::make_pair(this->emplace(it, name, std::move(action)), true);
20 }
21
22 auto ActionMap::Find(cm::string_view name) const -> const_iterator
23 {
24   auto const it =
25     std::lower_bound(this->begin(), this->end(), name,
26                      [](value_type const& elem, cm::string_view const& k) {
27                        return elem.first < k;
28                      });
29   return (it != this->end() && it->first == name) ? it : this->end();
30 }
31
32 void Instance::Bind(bool& val)
33 {
34   val = true;
35   this->CurrentString = nullptr;
36   this->CurrentList = nullptr;
37   this->ExpectValue = false;
38 }
39
40 void Instance::Bind(std::string& val)
41 {
42   this->CurrentString = &val;
43   this->CurrentList = nullptr;
44   this->ExpectValue = true;
45 }
46
47 void Instance::Bind(StringList& val)
48 {
49   this->CurrentString = nullptr;
50   this->CurrentList = &val;
51   this->ExpectValue = true;
52 }
53
54 void Instance::Bind(MultiStringList& val)
55 {
56   this->CurrentString = nullptr;
57   this->CurrentList = (static_cast<void>(val.emplace_back()), &val.back());
58   this->ExpectValue = false;
59 }
60
61 void Instance::Consume(cm::string_view arg, void* result,
62                        std::vector<std::string>* unparsedArguments,
63                        std::vector<std::string>* keywordsMissingValue,
64                        std::vector<std::string>* parsedKeywords)
65 {
66   auto const it = this->Bindings.Find(arg);
67   if (it != this->Bindings.end()) {
68     if (parsedKeywords != nullptr) {
69       parsedKeywords->emplace_back(arg);
70     }
71     it->second(*this, result);
72     if (this->ExpectValue && keywordsMissingValue != nullptr) {
73       keywordsMissingValue->emplace_back(arg);
74     }
75     return;
76   }
77
78   if (this->CurrentString != nullptr) {
79     this->CurrentString->assign(std::string(arg));
80     this->CurrentString = nullptr;
81     this->CurrentList = nullptr;
82   } else if (this->CurrentList != nullptr) {
83     this->CurrentList->emplace_back(arg);
84   } else if (unparsedArguments != nullptr) {
85     unparsedArguments->emplace_back(arg);
86   }
87
88   if (this->ExpectValue) {
89     if (keywordsMissingValue != nullptr) {
90       keywordsMissingValue->pop_back();
91     }
92     this->ExpectValue = false;
93   }
94 }
95
96 } // namespace ArgumentParser