Chaste  Release::2018.1
CommandLineArguments.cpp
1 /*
2 
3 Copyright (c) 2005-2018, University of Oxford.
4 All rights reserved.
5 
6 University of Oxford means the Chancellor, Masters and Scholars of the
7 University of Oxford, having an administrative office at Wellington
8 Square, Oxford OX1 2JD, UK.
9 
10 This file is part of Chaste.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright notice,
17  this list of conditions and the following disclaimer in the documentation
18  and/or other materials provided with the distribution.
19  * Neither the name of the University of Oxford nor the names of its
20  contributors may be used to endorse or promote products derived from this
21  software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34 */
35 
36 #include "CommandLineArguments.hpp"
37 
38 #include <cassert>
39 #include <cstddef>
40 #include <algorithm>
41 
43  : p_argc(nullptr),
44  p_argv(nullptr)
45 {
46  // Make doubly sure there's only one instance
47  assert(mpInstance == nullptr);
48 }
49 
51 {
52  if (mpInstance == nullptr)
53  {
55  }
56  return mpInstance;
57 }
58 
60 
61 bool CommandLineArguments::OptionExists(const std::string& rOption)
62 {
63  TestOptionFormat(rOption);
64  try
65  {
66  return(GetIndexForArgument(rOption));
67  }
68  catch (const Exception&)
69  {
70  return false;
71  }
72 }
73 
74 char* CommandLineArguments::GetValueCorrespondingToOption(const std::string& rOption, int valueNumber)
75 {
76  EXCEPT_IF_NOT(valueNumber>0);
77  TestOptionFormat(rOption);
78 
79  int index = GetIndexForArgument(rOption);
80  int num_args = GetNumberOfArgumentsForOption(rOption, true);
81  if (num_args < valueNumber)
82  {
83  std::stringstream ss;
84  ss<<"Index="<<valueNumber<<" requested for '"<<rOption<<"', but only "<<num_args<<" given.";
85  EXCEPTION(ss.str());
86  }
87 
88  return (*p_argv)[index+valueNumber];
89 }
90 
91 double CommandLineArguments::GetDoubleCorrespondingToOption(const std::string& rOption, int valueNumber)
92 {
93  char* val = GetValueCorrespondingToOption(rOption, valueNumber);
94  return atof(val);
95 }
96 
97 int CommandLineArguments::GetIntCorrespondingToOption(const std::string& rOption, int valueNumber)
98 {
99  char* val = GetValueCorrespondingToOption(rOption, valueNumber);
100  return atoi(val);
101 }
102 
103 unsigned CommandLineArguments::GetUnsignedCorrespondingToOption(const std::string& rOption, int valueNumber)
104 {
105  char* val = GetValueCorrespondingToOption(rOption, valueNumber);
106  int i = atoi(val);
107  if (i < 0)
108  {
109  EXCEPTION("Option is a negative number and cannot be converted to unsigned.");
110  }
111  return (unsigned)(i);
112 }
113 
115 {
116  TestOptionFormat(rOption);
117 
118  for (int i=1; i<*p_argc; i++)
119  {
120  if (rOption==std::string((*p_argv)[i]))
121  {
122  return i;
123  }
124  }
125  EXCEPTION("Command line option '"+rOption+"' does not exist");
126 }
127 
128 int CommandLineArguments::GetNumberOfArgumentsForOption(const std::string& rOption, bool throwIfNone)
129 {
130  int start_idx = GetIndexForArgument(rOption);
131 
132  int end_idx = start_idx;
133  for (int i=start_idx+1; i<*p_argc; i++)
134  {
135  std::string argument = std::string((*p_argv)[i]);
136  if (argument.substr(0,1)=="-" && argument.substr(1,1).find_first_of("0123456789")==std::string::npos)
137  {
138  break;
139  }
140  end_idx = i;
141  }
142 
143  if (end_idx == start_idx)
144  {
145  if (throwIfNone)
146  {
147  EXCEPTION("No value(s) given after command line option '" + rOption + "'");
148  }
149  else
150  {
151  return 0;
152  }
153  }
154 
155  return end_idx - start_idx;
156 }
157 
158 std::string CommandLineArguments::GetStringCorrespondingToOption(const std::string& rOption, int valueNumber)
159 {
160  char* val = GetValueCorrespondingToOption(rOption, valueNumber);
161  std::string string_arg(val);
162  return string_arg;
163 }
164 
165 std::vector<std::string> CommandLineArguments::GetStringsCorrespondingToOption(const std::string& rOption)
166 {
167  std::vector<std::string> strings;
168  int num_args = GetNumberOfArgumentsForOption(rOption, true);
169  for (int i=1; i<=num_args; ++i)
170  {
171  strings.push_back(GetStringCorrespondingToOption(rOption, i));
172  }
173  return strings;
174 }
175 
176 std::vector<double> CommandLineArguments::GetDoublesCorrespondingToOption(const std::string& rOption)
177 {
178  std::vector<double> doubles;
179  int num_args = GetNumberOfArgumentsForOption(rOption, true);
180  for (int i=1; i<=num_args; ++i)
181  {
182  doubles.push_back(GetDoubleCorrespondingToOption(rOption, i));
183  }
184  return doubles;
185 }
186 
187 std::vector<unsigned> CommandLineArguments::GetUnsignedsCorrespondingToOption(const std::string& rOption)
188 {
189  std::vector<unsigned> unsigneds;
190  int num_args = GetNumberOfArgumentsForOption(rOption, true);
191  for (int i=1; i<=num_args; ++i)
192  {
193  unsigneds.push_back(GetUnsignedCorrespondingToOption(rOption, i));
194  }
195  return unsigneds;
196 }
197 
198 std::vector<int> CommandLineArguments::GetIntsCorrespondingToOption(const std::string& rOption)
199 {
200  std::vector<int> ints;
201  int num_args = GetNumberOfArgumentsForOption(rOption, true);
202  for (int i=1; i<=num_args; ++i)
203  {
204  ints.push_back(GetIntCorrespondingToOption(rOption, i));
205  }
206  return ints;
207 }
208 
210 {
211  bool result;
212  std::string string_result = GetStringCorrespondingToOption(rOption);
213 
214  // Convert to lowercase
215  std::transform(string_result.begin(), string_result.end(), string_result.begin(), ::tolower);
216 
217  if (string_result=="0" || string_result=="false")
218  {
219  result = false;
220  }
221  else if (string_result=="1" || string_result=="true")
222  {
223  result = true;
224  }
225  else
226  {
227  EXCEPTION("The option '" << rOption << "' argument '" <<
228  GetStringCorrespondingToOption(rOption) << "' cannot be converted to a bool.");
229  }
230 
231  return result;
232 }
233 
234 void CommandLineArguments::TestOptionFormat(const std::string& rOption)
235 {
236  if (!( rOption.substr(0,1) == "-" && rOption.substr(1,1).find_first_of("0123456789")==std::string::npos))
237  {
238  EXCEPTION("A command line option must begin with '-' followed by a non-numeric character.");
239  }
240 }
std::vector< std::string > GetStringsCorrespondingToOption(const std::string &rOption)
std::vector< double > GetDoublesCorrespondingToOption(const std::string &rOption)
#define EXCEPTION(message)
Definition: Exception.hpp:143
char * GetValueCorrespondingToOption(const std::string &rOption, int valueNumber=1)
std::vector< unsigned > GetUnsignedsCorrespondingToOption(const std::string &rOption)
void TestOptionFormat(const std::string &rOption)
static CommandLineArguments * mpInstance
int GetIndexForArgument(std::string rOption)
bool OptionExists(const std::string &rOption)
std::vector< int > GetIntsCorrespondingToOption(const std::string &rOption)
bool GetBoolCorrespondingToOption(const std::string &rOption)
std::string GetStringCorrespondingToOption(const std::string &rOption, int valueNumber=1)
double GetDoubleCorrespondingToOption(const std::string &rOption, int valueNumber=1)
int GetIntCorrespondingToOption(const std::string &rOption, int valueNumber=1)
#define EXCEPT_IF_NOT(test)
Definition: Exception.hpp:158
static CommandLineArguments * Instance()
int GetNumberOfArgumentsForOption(const std::string &rOption, bool throwIfNone=false)
unsigned GetUnsignedCorrespondingToOption(const std::string &rOption, int valueNumber=1)