A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
command-line.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2008 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program 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 this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #include <algorithm> // for transform
22 #include <cctype> // for tolower
23 #include <cstdlib> // for exit
24 #include <iomanip> // for setw, boolalpha
25 
26 #include "command-line.h"
27 #include "log.h"
28 #include "config.h"
29 #include "global-value.h"
30 #include "system-path.h"
31 #include "type-id.h"
32 #include "string.h"
33 
34 
35 NS_LOG_COMPONENT_DEFINE ("CommandLine");
36 
37 namespace ns3 {
38 
40 {
41  NS_LOG_FUNCTION (this);
42 }
44 {
45  Copy (cmd);
46 }
49 {
50  Clear ();
51  Copy (cmd);
52  return *this;
53 }
55 {
56  NS_LOG_FUNCTION (this);
57  Clear ();
58 }
59 void
61 {
62  NS_LOG_FUNCTION (&cmd);
63 
64  for (Items::const_iterator i = cmd.m_items.begin ();
65  i != cmd.m_items.end (); ++i)
66  {
67  m_items.push_back (*i);
68  }
69  m_usage = cmd.m_usage;
70  m_name = cmd.m_name;
71 }
72 void
74 {
75  NS_LOG_FUNCTION (this);
76 
77  for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
78  {
79  delete *i;
80  }
81  m_items.clear ();
82  m_usage = "";
83  m_name = "";
84 }
85 
86 void
87 CommandLine::Usage (const std::string usage)
88 {
89  m_usage = usage;
90 }
91 
92 std::string
94 {
95  return m_name;
96 }
97 
99 {
100  NS_LOG_FUNCTION (this);
101 }
102 
103 void
104 CommandLine::Parse (int iargc, char *argv[])
105 {
106  NS_LOG_FUNCTION (this << iargc << argv);
107 
108  m_name = SystemPath::Split (argv[0]).back ();
109 
110  int argc = iargc;
111  for (argc--, argv++; argc > 0; argc--, argv++)
112  {
113  // remove "--" or "-" heading.
114  std::string param = *argv;
115  std::string::size_type cur = param.find ("--");
116  if (cur == 0)
117  {
118  param = param.substr (2, param.size () - 2);
119  }
120  else
121  {
122  cur = param.find ("-");
123  if (cur == 0)
124  {
125  param = param.substr (1, param.size () - 1);
126  }
127  else
128  {
129  // invalid argument. ignore.
130  continue;
131  }
132  }
133  cur = param.find ("=");
134  std::string name, value;
135  if (cur == std::string::npos)
136  {
137  name = param;
138  value = "";
139  }
140  else
141  {
142  name = param.substr (0, cur);
143  value = param.substr (cur + 1, param.size () - (cur+1));
144  }
145  HandleArgument (name, value);
146  }
147 }
148 
149 void
150 CommandLine::PrintHelp (std::ostream &os) const
151 {
152  NS_LOG_FUNCTION (this);
153 
154  os << m_name << " [Program Arguments] [General Arguments]"
155  << std::endl;
156 
157  if (m_usage.length ())
158  {
159  os << std::endl;
160  os << m_usage << std::endl;
161  }
162 
163  if (!m_items.empty ())
164  {
165  size_t width = 0;
166  for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
167  {
168  width = std::max (width, (*i)->m_name.size ());
169  }
170  width += 3;
171 
172  os << std::endl;
173  os << "Program Arguments:" << std::endl;
174  for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
175  {
176  os << " --"
177  << std::left << std::setw (width) << ( (*i)->m_name + ":")
178  << std::right
179  << (*i)->m_help;
180 
181  if ( (*i)->HasDefault ())
182  {
183  os << " [" << (*i)->GetDefault () << "]";
184  }
185  os << std::endl;
186  }
187  }
188 
189  os << std::endl;
190  os
191  << "General Arguments:\n"
192  << " --PrintGlobals: Print the list of globals.\n"
193  << " --PrintGroups: Print the list of groups.\n"
194  << " --PrintGroup=[group]: Print all TypeIds of group.\n"
195  << " --PrintTypeIds: Print all TypeIds.\n"
196  << " --PrintAttributes=[typeid]: Print all attributes of typeid.\n"
197  << " --PrintHelp: Print this help message.\n"
198  << std::endl;
199 }
200 
201 void
202 CommandLine::PrintGlobals (std::ostream &os) const
203 {
204  NS_LOG_FUNCTION (this);
205 
206  os << "Global values:" << std::endl;
207 
209  i != GlobalValue::End ();
210  ++i)
211  {
212  os << " --" << (*i)->GetName () << "=[";
213  Ptr<const AttributeChecker> checker = (*i)->GetChecker ();
214  StringValue v;
215  (*i)->GetValue (v);
216  os << v.Get () << "]" << std::endl;
217  os << " " << (*i)->GetHelp () << std::endl;
218  }
219 }
220 
221 void
222 CommandLine::PrintAttributes (std::ostream &os, const std::string &type) const
223 {
224  NS_LOG_FUNCTION (this);
225 
226  TypeId tid;
227  if (!TypeId::LookupByNameFailSafe (type, &tid))
228  {
229  NS_FATAL_ERROR ("Unknown type=" << type << " in --PrintAttributes");
230  }
231 
232  os << "Attributes for TypeId " << tid.GetName () << std::endl;
233 
234  for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
235  {
236  os << " --" << tid.GetAttributeFullName (i) << "=[";
237  struct TypeId::AttributeInformation info = tid.GetAttribute (i);
238  os << info.initialValue->SerializeToString (info.checker) << "]"
239  << std::endl;
240  os << " " << info.help << std::endl;
241  }
242 }
243 
244 
245 void
246 CommandLine::PrintGroup (std::ostream &os, const std::string &group) const
247 {
248  NS_LOG_FUNCTION (this);
249 
250  os << "TypeIds in group " << group << ":" << std::endl;
251 
252  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
253  {
254  TypeId tid = TypeId::GetRegistered (i);
255  if (tid.GetGroupName () == group)
256  {
257  os << " " <<tid.GetName () << std::endl;
258  }
259  }
260 }
261 
262 void
263 CommandLine::PrintTypeIds (std::ostream &os) const
264 {
265  NS_LOG_FUNCTION (this);
266  os << "Registered TypeIds:" << std::endl;
267  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
268  {
269  TypeId tid = TypeId::GetRegistered (i);
270  os << " " << tid.GetName () << std::endl;
271  }
272 }
273 
274 void
275 CommandLine::PrintGroups (std::ostream &os) const
276 {
277  NS_LOG_FUNCTION (this);
278 
279  std::list<std::string> groups;
280  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
281  {
282  TypeId tid = TypeId::GetRegistered (i);
283  std::string group = tid.GetGroupName ();
284  if (group == "")
285  {
286  continue;
287  }
288  bool found = false;
289  for (std::list<std::string>::const_iterator j = groups.begin ();
290  j != groups.end ();
291  ++j)
292  {
293  if (*j == group)
294  {
295  found = true;
296  break;
297  }
298  }
299  if (!found)
300  {
301  groups.push_back (group);
302  }
303  }
304 
305  os << "Registered TypeId groups:" << std::endl;
306 
307  for (std::list<std::string>::const_iterator k = groups.begin ();
308  k != groups.end ();
309  ++k)
310  {
311  os << " " << *k << std::endl;
312  }
313 }
314 
315 void
316 CommandLine::HandleArgument (const std::string &name, const std::string &value) const
317 {
318  NS_LOG_FUNCTION (this << name << value);
319 
320  NS_LOG_DEBUG ("Handle arg name=" << name << " value=" << value);
321  if (name == "PrintHelp" || name == "help")
322  {
323  // method below never returns.
324  PrintHelp (std::cout);
325  std::exit (0);
326  }
327  else if (name == "PrintGroups")
328  {
329  // method below never returns.
330  PrintGroups (std::cout);
331  std::exit (0);
332  }
333  else if (name == "PrintTypeIds")
334  {
335  // method below never returns.
336  PrintTypeIds (std::cout);
337  std::exit (0);
338  }
339  else if (name == "PrintGlobals")
340  {
341  // method below never returns.
342  PrintGlobals (std::cout);
343  std::exit (0);
344  }
345  else if (name == "PrintGroup")
346  {
347  // method below never returns.
348  PrintGroup (std::cout, value);
349  std::exit (0);
350  }
351  else if (name == "PrintAttributes")
352  {
353  // method below never returns.
354  PrintAttributes (std::cout, value);
355  std::exit (0);
356  }
357  else
358  {
359  for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
360  {
361  if ((*i)->m_name == name)
362  {
363  if (!(*i)->Parse (value))
364  {
365  std::cerr << "Invalid argument value: "
366  << name << "=" << value << std::endl;
367  std::exit (1);
368  }
369  else
370  {
371  return;
372  }
373  }
374  }
375  }
376  if (!Config::SetGlobalFailSafe (name, StringValue (value))
377  && !Config::SetDefaultFailSafe (name, StringValue (value)))
378  {
379  std::cerr << "Invalid command-line arguments: --"
380  << name << "=" << value << std::endl;
381  PrintHelp (std::cerr);
382  std::exit (1);
383  }
384 }
385 
386 bool
387 CommandLine::CallbackItem::Parse (const std::string value)
388 {
389  NS_LOG_FUNCTION (this);
390  NS_LOG_DEBUG ("CommandLine::CallbackItem::Parse \"" << value << "\"");
391  return m_callback (value);
392 }
393 
394 void
395 CommandLine::AddValue (const std::string &name,
396  const std::string &help,
398 {
399  NS_LOG_FUNCTION (this << &name << &help << &callback);
400  CallbackItem *item = new CallbackItem ();
401  item->m_name = name;
402  item->m_help = help;
403  item->m_callback = callback;
404  m_items.push_back (item);
405 }
406 
407 
408 bool
410 {
411  return false;
412 }
413 
414 std::string
416 {
417  return "";
418 }
419 
420 template <>
421 std::string
423 {
424  std::ostringstream oss;
425  oss << std::boolalpha << val;
426  return oss.str ();
427 }
428 
429 template <>
430 bool
431 CommandLineHelper::UserItemParse<bool> (const std::string value, bool & val)
432 {
433  std::string src = value;
434  std::transform(src.begin(), src.end(), src.begin(), ::tolower);
435 
436  if (src.length () == 0)
437  {
438  val = ! val;
439  return true;
440  }
441  else if ( (src == "true") || (src == "t") )
442  {
443  val = true;
444  return true;
445  }
446  else if ( (src == "false") || (src == "f"))
447  {
448  val = false;
449  return true;
450  }
451  else
452  {
453  std::istringstream iss;
454  iss.str (src);
455  iss >> val;
456  return !iss.bad () && !iss.fail ();
457  }
458 }
459 
460 } // namespace ns3
~CommandLine()
Destructor.
Definition: command-line.cc:54
uint32_t GetAttributeN(void) const
Definition: type-id.cc:739
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
std::string Get(void) const
Items m_items
The list of arguments.
Definition: command-line.h:354
hold variables of type string
Definition: string.h:19
void PrintGlobals(std::ostream &os) const
Handler for --PrintGlobals: print all global variables and values.
Vector::const_iterator Iterator
Definition: global-value.h:51
static bool LookupByNameFailSafe(std::string name, TypeId *tid)
Definition: type-id.cc:544
std::string GetDefault< bool >(const bool &val)
Helper to specialize UserItem::GetDefault on bool.
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
std::string GetName() const
Get the program name.
Definition: command-line.cc:93
void Usage(const std::string usage)
Supply the program usage and documentation.
Definition: command-line.cc:87
bool SetDefaultFailSafe(std::string fullName, const AttributeValue &value)
Definition: config.cc:675
void Clear(void)
Remove all arguments, Usage(), name.
Definition: command-line.cc:73
void PrintAttributes(std::ostream &os, const std::string &type) const
Handler for --PrintAttributes: print the attributes for a given type.
NS_LOG_COMPONENT_DEFINE("CommandLine")
An argument Item using a Callback to parse the input.
Definition: command-line.h:305
void PrintHelp(std::ostream &os) const
Print program usage to the desired output stream.
std::string m_usage
The Usage string.
Definition: command-line.h:355
static uint32_t GetRegisteredN(void)
Definition: type-id.cc:576
virtual std::string GetDefault() const
static Iterator Begin(void)
Ptr< const AttributeValue > initialValue
Definition: type-id.h:66
static TypeId GetRegistered(uint32_t i)
Definition: type-id.cc:582
std::string m_name
The program name.
Definition: command-line.h:356
Parse command-line arguments.
Definition: command-line.h:152
virtual bool Parse(const std::string value)
Parse from a string.
void PrintGroups(std::ostream &os) const
Handler for --PrintGroups: print all TypeId group names.
Ptr< const AttributeChecker > checker
Definition: type-id.h:68
CommandLine & operator=(const CommandLine &cmd)
Assignment.
Definition: command-line.cc:48
std::string m_name
Argument label: ---m_name=...
Definition: command-line.h:258
bool UserItemParse< bool >(const std::string value, bool &val)
Helper to specialize UserItem::Parse on bool.
Callback< bool, std::string > m_callback
The Callback.
Definition: command-line.h:315
std::string GetName(void) const
Definition: type-id.cc:658
virtual bool HasDefault() const
virtual ~Item()
Destructor.
Definition: command-line.cc:98
bool SetGlobalFailSafe(std::string name, const AttributeValue &value)
Definition: config.cc:712
std::string m_help
Argument help string.
Definition: command-line.h:259
CommandLine()
Constructor.
Definition: command-line.cc:39
void AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
Definition: command-line.h:408
static Iterator End(void)
#define NS_LOG_DEBUG(msg)
Definition: log.h:289
void PrintTypeIds(std::ostream &os) const
Handler for --PrintTypeIds: print all TypeId names.
void Copy(const CommandLine &cmd)
Copy constructor.
Definition: command-line.cc:60
void PrintGroup(std::ostream &os, const std::string &group) const
Handler for --PrintGroup: print all types belonging to a given group.
std::string GetAttributeFullName(uint32_t i) const
Definition: type-id.cc:752
void Parse(int argc, char *argv[])
Parse the program arguments.
std::string GetGroupName(void) const
Definition: type-id.cc:650
struct TypeId::AttributeInformation GetAttribute(uint32_t i) const
Definition: type-id.cc:746
std::list< std::string > Split(std::string path)
Definition: system-path.cc:180
a unique identifier for an interface.
Definition: type-id.h:49
void HandleArgument(const std::string &name, const std::string &value) const
Match name against the program or general arguments, and dispatch to the appropriate handler...