Chaste  Release::3.4
CommandLineArguments.cpp
1 /*
2 
3 Copyright (c) 2005-2016, 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(NULL),
44  p_argv(NULL)
45 {
46  // Make doubly sure there's only one instance
47  assert(mpInstance == NULL);
48 }
49 
51 {
52  if (mpInstance == NULL)
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 
156  return end_idx - start_idx;
157 }
158 
159 std::string CommandLineArguments::GetStringCorrespondingToOption(const std::string& rOption, int valueNumber)
160 {
161  char* val = GetValueCorrespondingToOption(rOption, valueNumber);
162  std::string string_arg(val);
163  return string_arg;
164 }
165 
166 std::vector<std::string> CommandLineArguments::GetStringsCorrespondingToOption(const std::string& rOption)
167 {
168  std::vector<std::string> strings;
169  int num_args = GetNumberOfArgumentsForOption(rOption, true);
170  for(int i=1; i<=num_args; ++i)
171  {
172  strings.push_back(GetStringCorrespondingToOption(rOption, i));
173  }
174  return strings;
175 }
176 
177 std::vector<double> CommandLineArguments::GetDoublesCorrespondingToOption(const std::string& rOption)
178 {
179  std::vector<double> doubles;
180  int num_args = GetNumberOfArgumentsForOption(rOption, true);
181  for(int i=1; i<=num_args; ++i)
182  {
183  doubles.push_back(GetDoubleCorrespondingToOption(rOption, i));
184  }
185  return doubles;
186 }
187 
188 std::vector<unsigned> CommandLineArguments::GetUnsignedsCorrespondingToOption(const std::string& rOption)
189 {
190  std::vector<unsigned> unsigneds;
191  int num_args = GetNumberOfArgumentsForOption(rOption, true);
192  for(int i=1; i<=num_args; ++i)
193  {
194  unsigneds.push_back(GetUnsignedCorrespondingToOption(rOption, i));
195  }
196  return unsigneds;
197 }
198 
199 std::vector<int> CommandLineArguments::GetIntsCorrespondingToOption(const std::string& rOption)
200 {
201  std::vector<int> ints;
202  int num_args = GetNumberOfArgumentsForOption(rOption, true);
203  for(int i=1; i<=num_args; ++i)
204  {
205  ints.push_back(GetIntCorrespondingToOption(rOption, i));
206  }
207  return ints;
208 }
209 
211 {
212  bool result;
213  std::string string_result = GetStringCorrespondingToOption(rOption);
214 
215  // Convert to lowercase
216  std::transform(string_result.begin(), string_result.end(), string_result.begin(), ::tolower);
217 
218  if (string_result=="0" || string_result=="false")
219  {
220  result = false;
221  }
222  else if (string_result=="1" || string_result=="true")
223  {
224  result = true;
225  }
226  else
227  {
228  EXCEPTION("The option '" << rOption << "' argument '" <<
229  GetStringCorrespondingToOption(rOption) << "' cannot be converted to a bool.");
230  }
231 
232  return result;
233 }
234 
235 void CommandLineArguments::TestOptionFormat(const std::string& rOption)
236 {
237  if ( !( rOption.substr(0,1) == "-" && rOption.substr(1,1).find_first_of("0123456789")==std::string::npos ) )
238  {
239  EXCEPTION("A command line option must begin with '-' followed by a non-numeric character.");
240  }
241 }
242 
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)