SIRIUS 7.5.0
Electronic structure library and applications
cmd_args.cpp
Go to the documentation of this file.
1// Copyright (c) 2013-2020 Anton Kozhevnikov, Thomas Schulthess
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
5// the following conditions are met:
6//
7// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
8// following disclaimer.
9// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
10// and the following disclaimer in the documentation and/or other materials provided with the distribution.
11//
12// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
13// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
14// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
15// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
16// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
17// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
18// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19
20/** \file cmd_args.cpp
21 *
22 * \brief Contains definition on cmd_args class.
23 *
24 */
25
26#include "core/cmd_args.hpp"
27
28namespace sirius {
29
30void cmd_args::check_for_key(std::string const key__) const
31{
32 if (!exist(key__)) {
33 std::stringstream s;
34 s << "command line parameter --" << key__ << " was not specified";
35 throw std::runtime_error(s.str());
36 }
37}
38
40{
41 register_key("--help", "print this help and exit");
42}
43
44cmd_args::cmd_args(int argn__, char** argv__, std::initializer_list<std::pair<std::string, std::string>> keys__)
45{
46 register_key("--help", "print this help and exit");
47 for (auto key : keys__) {
48 register_key("--" + key.first, key.second);
49 }
50 parse_args(argn__, argv__);
51}
52
53void cmd_args::register_key(std::string const key__, std::string const description__)
54{
55 key_desc_.push_back(std::pair<std::string, std::string>(key__, description__));
56
57 int key_type = 0;
58 std::string key = key__.substr(2, key__.length());
59
60 if (key[key.length() - 1] == '=') {
61 key = key.substr(0, key.length() - 1);
62 key_type = 1;
63 }
64
65 if (known_keys_.count(key) != 0) {
66 std::stringstream s;
67 s << "key (" << key << ") is already registered";
68 throw std::runtime_error(s.str());
69 }
70
71 known_keys_[key] = key_type;
72}
73
74void cmd_args::parse_args(int argn__, char** argv__)
75{
76 for (int i = 1; i < argn__; i++) {
77 std::string str(argv__[i]);
78 if (str.length() < 3 || str[0] != '-' || str[1] != '-') {
79 std::stringstream s;
80 s << "wrong key: " << str;
81 throw std::runtime_error(s.str());
82 }
83
84 size_t k = str.find("=");
85
86 std::string key, val;
87 if (k != std::string::npos) {
88 key = str.substr(2, k - 2);
89 val = str.substr(k + 1, str.length());
90 } else {
91 key = str.substr(2, str.length());
92 }
93
94 if (known_keys_.count(key) != 1) {
95 std::stringstream s;
96 s << "key " << key << " is not found";
97 throw std::runtime_error(s.str());
98 }
99
100 if (known_keys_[key] == 0 && k != std::string::npos) {
101 throw std::runtime_error("this key must not have a value");
102 }
103
104 if (known_keys_[key] == 1 && k == std::string::npos) {
105 throw std::runtime_error("this key must have a value");
106 }
107
108 if (keys_.count(key) != 0) {
109 std::stringstream s;
110 s << "key (" << key << ") is already added";
111 throw std::runtime_error(s.str());
112 }
113
114 keys_[key] = val;
115 }
116 if (this->exist("help")) {
117 printf("Usage: %s [options]\n", argv__[0]);
118 this->print_help();
119 exit(0);
120 }
121}
122
123void cmd_args::print_help()
124{
125 int max_key_width = 0;
126 for (int i = 0; i < (int)key_desc_.size(); i++) {
127 max_key_width = std::max(max_key_width, (int)key_desc_[i].first.length());
128 }
129
130 std::printf("Options:\n");
131
132 for (int i = 0; i < (int)key_desc_.size(); i++) {
133 std::printf(" %s", key_desc_[i].first.c_str());
134 int k = (int)key_desc_[i].first.length();
135
136 for (int j = 0; j < max_key_width - k + 1; j++) {
137 std::printf(" ");
138 }
139
140 std::printf("%s\n", key_desc_[i].second.c_str());
141 }
142}
143
144} // namespace sirius
std::vector< std::pair< std::string, std::string > > key_desc_
Helper string for each key.
Definition: cmd_args.hpp:42
cmd_args()
Constructor.
Definition: cmd_args.cpp:39
std::map< std::string, int > known_keys_
Mapping between a key and its kind (with or without value).
Definition: cmd_args.hpp:45
std::map< std::string, std::string > keys_
Key to value mapping.
Definition: cmd_args.hpp:48
Contains definition and implementation of cmd_args class.
@ key
the parser read a key of a value in an object
Namespace of the SIRIUS library.
Definition: sirius.f90:5