A Discrete-Event Network Simulator
API
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 #include <set>
26 #include <sstream>
27 
28 #include "command-line.h"
29 #include "des-metrics.h"
30 #include "log.h"
31 #include "config.h"
32 #include "global-value.h"
33 #include "system-path.h"
34 #include "type-id.h"
35 #include "string.h"
36 
37 
44 namespace ns3 {
45 
46 NS_LOG_COMPONENT_DEFINE ("CommandLine");
47 
49 {
50  NS_LOG_FUNCTION (this);
51 }
53 {
54  Copy (cmd);
55 }
58 {
59  Clear ();
60  Copy (cmd);
61  return *this;
62 }
64 {
65  NS_LOG_FUNCTION (this);
66  Clear ();
67 }
68 void
70 {
71  NS_LOG_FUNCTION (&cmd);
72 
73  for (Items::const_iterator i = cmd.m_items.begin ();
74  i != cmd.m_items.end (); ++i)
75  {
76  m_items.push_back (*i);
77  }
78  m_usage = cmd.m_usage;
79  m_name = cmd.m_name;
80 }
81 void
83 {
84  NS_LOG_FUNCTION (this);
85 
86  for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
87  {
88  delete *i;
89  }
90  m_items.clear ();
91  m_usage = "";
92  m_name = "";
93 }
94 
95 void
96 CommandLine::Usage (const std::string usage)
97 {
98  m_usage = usage;
99 }
100 
101 std::string
103 {
104  return m_name;
105 }
106 
108 {
109  NS_LOG_FUNCTION (this);
110 }
111 
112 void
113 CommandLine::Parse (int argc, char *argv[])
114 {
115  NS_LOG_FUNCTION (this << argc << argv);
116 
117  m_name = SystemPath::Split (argv[0]).back ();
118 
119  for (int iargc = 1; iargc < argc; iargc++)
120  {
121  // remove "--" or "-" heading.
122  std::string param = argv[iargc];
123  std::string::size_type cur = param.find ("--");
124  if (cur == 0)
125  {
126  param = param.substr (2, param.size () - 2);
127  }
128  else
129  {
130  cur = param.find ("-");
131  if (cur == 0)
132  {
133  param = param.substr (1, param.size () - 1);
134  }
135  else
136  {
137  // invalid argument. ignore.
138  continue;
139  }
140  }
141  cur = param.find ("=");
142  std::string name, value;
143  if (cur == std::string::npos)
144  {
145  name = param;
146  value = "";
147  }
148  else
149  {
150  name = param.substr (0, cur);
151  value = param.substr (cur + 1, param.size () - (cur+1));
152  }
153  HandleArgument (name, value);
154  }
155 
156 #ifdef ENABLE_DES_METRICS
157  DesMetrics::Get ()->Initialize (argc, argv);
158 #endif
159 
160 }
161 
162 void
163 CommandLine::PrintHelp (std::ostream &os) const
164 {
165  NS_LOG_FUNCTION (this);
166 
167  os << m_name << " [Program Arguments] [General Arguments]"
168  << std::endl;
169 
170  if (m_usage.length ())
171  {
172  os << std::endl;
173  os << m_usage << std::endl;
174  }
175 
176  if (!m_items.empty ())
177  {
178  size_t width = 0;
179  for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
180  {
181  width = std::max (width, (*i)->m_name.size ());
182  }
183  width += 3;
184 
185  os << std::endl;
186  os << "Program Arguments:" << std::endl;
187  for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
188  {
189  os << " --"
190  << std::left << std::setw (width) << ( (*i)->m_name + ":")
191  << std::right
192  << (*i)->m_help;
193 
194  if ( (*i)->HasDefault ())
195  {
196  os << " [" << (*i)->GetDefault () << "]";
197  }
198  os << std::endl;
199  }
200  }
201 
202  os << std::endl;
203  os
204  << "General Arguments:\n"
205  << " --PrintGlobals: Print the list of globals.\n"
206  << " --PrintGroups: Print the list of groups.\n"
207  << " --PrintGroup=[group]: Print all TypeIds of group.\n"
208  << " --PrintTypeIds: Print all TypeIds.\n"
209  << " --PrintAttributes=[typeid]: Print all attributes of typeid.\n"
210  << " --PrintHelp: Print this help message.\n"
211  << std::endl;
212 }
213 
214 void
215 CommandLine::PrintGlobals (std::ostream &os) const
216 {
217  NS_LOG_FUNCTION (this);
218 
219  os << "Global values:" << std::endl;
220 
221  // Sort output
222  std::vector<std::string> globals;
223 
225  i != GlobalValue::End ();
226  ++i)
227  {
228  std::stringstream ss;
229  ss << " --" << (*i)->GetName () << "=[";
230  Ptr<const AttributeChecker> checker = (*i)->GetChecker ();
231  StringValue v;
232  (*i)->GetValue (v);
233  ss << v.Get () << "]" << std::endl;
234  ss << " " << (*i)->GetHelp () << std::endl;
235  globals.push_back (ss.str ());
236  }
237  std::sort (globals.begin (), globals.end ());
238  for (std::vector<std::string>::const_iterator it = globals.begin ();
239  it < globals.end ();
240  ++it)
241  {
242  os << *it;
243  }
244 }
245 
246 void
247 CommandLine::PrintAttributes (std::ostream &os, const std::string &type) const
248 {
249  NS_LOG_FUNCTION (this);
250 
251  TypeId tid;
252  if (!TypeId::LookupByNameFailSafe (type, &tid))
253  {
254  NS_FATAL_ERROR ("Unknown type=" << type << " in --PrintAttributes");
255  }
256 
257  os << "Attributes for TypeId " << tid.GetName () << std::endl;
258 
259  // Sort output
260  std::vector<std::string> attributes;
261 
262  for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
263  {
264  std::stringstream ss;
265  ss << " --" << tid.GetAttributeFullName (i) << "=[";
266  struct TypeId::AttributeInformation info = tid.GetAttribute (i);
267  ss << info.initialValue->SerializeToString (info.checker) << "]"
268  << std::endl;
269  ss << " " << info.help << std::endl;
270  attributes.push_back (ss.str ());
271  }
272  std::sort (attributes.begin (), attributes.end ());
273  for (std::vector<std::string>::const_iterator it = attributes.begin ();
274  it < attributes.end ();
275  ++it)
276  {
277  os << *it;
278  }
279 }
280 
281 
282 void
283 CommandLine::PrintGroup (std::ostream &os, const std::string &group) const
284 {
285  NS_LOG_FUNCTION (this);
286 
287  os << "TypeIds in group " << group << ":" << std::endl;
288 
289  // Sort output
290  std::vector<std::string> groupTypes;
291 
292  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
293  {
294  std::stringstream ss;
295  TypeId tid = TypeId::GetRegistered (i);
296  if (tid.GetGroupName () == group)
297  {
298  ss << " " <<tid.GetName () << std::endl;
299  }
300  groupTypes.push_back (ss.str ());
301  }
302  std::sort (groupTypes.begin (), groupTypes.end ());
303  for (std::vector<std::string>::const_iterator it = groupTypes.begin ();
304  it < groupTypes.end ();
305  ++it)
306  {
307  os << *it;
308  }
309 }
310 
311 void
312 CommandLine::PrintTypeIds (std::ostream &os) const
313 {
314  NS_LOG_FUNCTION (this);
315  os << "Registered TypeIds:" << std::endl;
316 
317  // Sort output
318  std::vector<std::string> types;
319 
320  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
321  {
322  std::stringstream ss;
323  TypeId tid = TypeId::GetRegistered (i);
324  ss << " " << tid.GetName () << std::endl;
325  types.push_back (ss.str ());
326  }
327  std::sort (types.begin (), types.end ());
328  for (std::vector<std::string>::const_iterator it = types.begin ();
329  it < types.end ();
330  ++it)
331  {
332  os << *it;
333  }
334 }
335 
336 void
337 CommandLine::PrintGroups (std::ostream &os) const
338 {
339  NS_LOG_FUNCTION (this);
340 
341  std::set<std::string> groups;
342  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
343  {
344  TypeId tid = TypeId::GetRegistered (i);
345  groups.insert (tid.GetGroupName ());
346  }
347 
348  os << "Registered TypeId groups:" << std::endl;
349  // Sets are already sorted
350  for (std::set<std::string>::const_iterator k = groups.begin ();
351  k != groups.end ();
352  ++k)
353  {
354  os << " " << *k << std::endl;
355  }
356 }
357 
358 void
359 CommandLine::HandleArgument (const std::string &name, const std::string &value) const
360 {
361  NS_LOG_FUNCTION (this << name << value);
362 
363  NS_LOG_DEBUG ("Handle arg name=" << name << " value=" << value);
364  if (name == "PrintHelp" || name == "help")
365  {
366  // method below never returns.
367  PrintHelp (std::cout);
368  std::exit (0);
369  }
370  else if (name == "PrintGroups")
371  {
372  // method below never returns.
373  PrintGroups (std::cout);
374  std::exit (0);
375  }
376  else if (name == "PrintTypeIds")
377  {
378  // method below never returns.
379  PrintTypeIds (std::cout);
380  std::exit (0);
381  }
382  else if (name == "PrintGlobals")
383  {
384  // method below never returns.
385  PrintGlobals (std::cout);
386  std::exit (0);
387  }
388  else if (name == "PrintGroup")
389  {
390  // method below never returns.
391  PrintGroup (std::cout, value);
392  std::exit (0);
393  }
394  else if (name == "PrintAttributes")
395  {
396  // method below never returns.
397  PrintAttributes (std::cout, value);
398  std::exit (0);
399  }
400  else
401  {
402  for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
403  {
404  if ((*i)->m_name == name)
405  {
406  if (!(*i)->Parse (value))
407  {
408  std::cerr << "Invalid argument value: "
409  << name << "=" << value << std::endl;
410  std::exit (1);
411  }
412  else
413  {
414  return;
415  }
416  }
417  }
418  }
419  if (!Config::SetGlobalFailSafe (name, StringValue (value))
420  && !Config::SetDefaultFailSafe (name, StringValue (value)))
421  {
422  std::cerr << "Invalid command-line arguments: --"
423  << name << "=" << value << std::endl;
424  PrintHelp (std::cerr);
425  std::exit (1);
426  }
427 }
428 
429 bool
430 CommandLine::CallbackItem::Parse (const std::string value)
431 {
432  NS_LOG_FUNCTION (this);
433  NS_LOG_DEBUG ("CommandLine::CallbackItem::Parse \"" << value << "\"");
434  return m_callback (value);
435 }
436 
437 void
438 CommandLine::AddValue (const std::string &name,
439  const std::string &help,
441 {
442  NS_LOG_FUNCTION (this << &name << &help << &callback);
443  CallbackItem *item = new CallbackItem ();
444  item->m_name = name;
445  item->m_help = help;
446  item->m_callback = callback;
447  m_items.push_back (item);
448 }
449 
450 void
451 CommandLine::AddValue (const std::string &name,
452  const std::string &attributePath)
453 {
454  NS_LOG_FUNCTION (this << name << attributePath);
455  // Attribute name is last token
456  size_t colon = attributePath.rfind ("::");
457  const std::string typeName = attributePath.substr (0, colon);
458  NS_LOG_DEBUG ("typeName: '" << typeName << "', colon: " << colon);
459 
460  TypeId tid;
461  if (!TypeId::LookupByNameFailSafe (typeName, &tid))
462  {
463  NS_FATAL_ERROR ("Unknown type=" << typeName);
464  }
465 
466  const std::string attrName = attributePath.substr (colon + 2);
467  struct TypeId::AttributeInformation info;
468  if (!tid.LookupAttributeByName (attrName, &info))
469  {
470  NS_FATAL_ERROR ("Attribute not found: " << attributePath);
471  }
472 
473  std::stringstream ss;
474  ss << info.help
475  << " (" << attributePath << ") ["
476  << info.initialValue->SerializeToString (info.checker) << "]";
477 
478  AddValue (name, ss.str (),
480 }
481 
482 
483 /* static */
484 bool
485 CommandLine::HandleAttribute (const std::string name,
486  const std::string value)
487 {
488  bool success = true;
489  if (!Config::SetGlobalFailSafe (name, StringValue (value))
490  && !Config::SetDefaultFailSafe (name, StringValue (value)))
491  {
492  success = false;
493  }
494  return success;
495 }
496 
497 
498 bool
500 {
501  return false;
502 }
503 
504 std::string
506 {
507  return "";
508 }
509 
510 template <>
511 std::string
513 {
514  std::ostringstream oss;
515  oss << std::boolalpha << val;
516  return oss.str ();
517 }
518 
519 template <>
520 bool
521 CommandLineHelper::UserItemParse<bool> (const std::string value, bool & val)
522 {
523  std::string src = value;
524  std::transform(src.begin(), src.end(), src.begin(), ::tolower);
525 
526  if (src.length () == 0)
527  {
528  val = ! val;
529  return true;
530  }
531  else if ( (src == "true") || (src == "t") )
532  {
533  val = true;
534  return true;
535  }
536  else if ( (src == "false") || (src == "f"))
537  {
538  val = false;
539  return true;
540  }
541  else
542  {
543  std::istringstream iss;
544  iss.str (src);
545  iss >> val;
546  return !iss.bad () && !iss.fail ();
547  }
548 }
549 
550 std::ostream &
551 operator << (std::ostream & os, const CommandLine & cmd)
552 {
553  cmd.PrintHelp (os);
554  return os;
555 }
556 
557 } // namespace ns3
~CommandLine()
Destructor.
Definition: command-line.cc:63
uint32_t GetAttributeN(void) const
Get the number of attributes.
Definition: type-id.cc:1068
void Initialize(int argc, char *argv[], std::string outDir="")
Open the DesMetrics trace file and print the header.
Definition: des-metrics.cc:42
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
bool SetDefaultFailSafe(std::string fullName, const AttributeValue &value)
Definition: config.cc:790
std::string Get(void) const
Definition: string.cc:31
Items m_items
The list of arguments.
Definition: command-line.h:439
Hold variables of type string.
Definition: string.h:41
ns3::StringValue attribute value declarations.
bool SetGlobalFailSafe(std::string name, const AttributeValue &value)
Definition: config.cc:827
void PrintGlobals(std::ostream &os) const
Handler for --PrintGlobals: print all global variables and values.
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
Definition: callback.h:1686
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
Vector::const_iterator Iterator
Iterator type for the list of all global values.
Definition: global-value.h:80
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
static bool LookupByNameFailSafe(std::string name, TypeId *tid)
Get a TypeId by name.
Definition: type-id.cc:831
std::string GetDefault< bool >(const bool &val)
Helper to specialize CommandLine::UserItem::GetDefault() on bool.
Declaration of the various ns3::Config functions and classes.
static DesMetrics * Get(void)
Get a pointer to the singleton instance.
ns3::DesMetrics declaration.
tuple cmd
Definition: second.py:35
std::list< std::string > Split(std::string path)
Split a file system path into directories according to the local path separator.
Definition: system-path.cc:205
std::string GetName() const
Get the program name.
void Usage(const std::string usage)
Supply the program usage and documentation.
Definition: command-line.cc:96
ns3::SystemPath declarations.
void Clear(void)
Remove all arguments, Usage(), name.
Definition: command-line.cc:82
void PrintAttributes(std::ostream &os, const std::string &type) const
Handler for --PrintAttributes: print the attributes for a given type.
An argument Item using a Callback to parse the input.
Definition: command-line.h:368
void PrintHelp(std::ostream &os) const
Print program usage to the desired output stream.
static bool HandleAttribute(const std::string name, const std::string value)
Callback function to handle attributes.
std::string m_usage
The Usage string.
Definition: command-line.h:440
#define max(a, b)
Definition: 80211b.c:45
static uint32_t GetRegisteredN(void)
Get the number of registered TypeIds.
Definition: type-id.cc:863
virtual std::string GetDefault() const
static Iterator Begin(void)
The Begin iterator.
Ptr< const AttributeValue > initialValue
Configured initial value.
Definition: type-id.h:86
static TypeId GetRegistered(uint32_t i)
Get a TypeId by index.
Definition: type-id.cc:869
std::string m_name
The program name.
Definition: command-line.h:441
Attribute implementation.
Definition: type-id.h:76
Parse command-line arguments.
Definition: command-line.h:205
virtual bool Parse(const std::string value)
Parse from a string.
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:42
void PrintGroups(std::ostream &os) const
Handler for --PrintGroups: print all TypeId group names.
ns3::CommandLine declaration.
Ptr< const AttributeChecker > checker
Checker object.
Definition: type-id.h:90
Every class exported by the ns3 library is enclosed in the ns3 namespace.
CommandLine & operator=(const CommandLine &cmd)
Assignment.
Definition: command-line.cc:57
bool LookupAttributeByName(std::string name, struct AttributeInformation *info) const
Find an Attribute by name, retrieving the associated AttributeInformation.
Definition: type-id.cc:876
ns3::TypeId declaration; inline and template implementations.
std::string m_name
Argument label: ---m_name=...
Definition: command-line.h:321
bool UserItemParse< bool >(const std::string value, bool &val)
Helpers to specialize CommandLine::UserItem::Parse() on bool.
Callback< bool, std::string > m_callback
The Callback.
Definition: command-line.h:378
std::string GetName(void) const
Get the name.
Definition: type-id.cc:968
ns3::GlobalValue declaration.
virtual bool HasDefault() const
virtual ~Item()
Destructor.
if(desigRtr==addrLocal)
std::string m_help
Argument help string.
Definition: command-line.h:322
CommandLine()
Constructor.
Definition: command-line.cc:48
void AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
Definition: command-line.h:498
static Iterator End(void)
The End iterator.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:269
void PrintTypeIds(std::ostream &os) const
Handler for --PrintTypeIds: print all TypeId names.
void Copy(const CommandLine &cmd)
Copy constructor.
Definition: command-line.cc:69
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
Get the Attribute name by index.
Definition: type-id.cc:1081
void Parse(int argc, char *argv[])
Parse the program arguments.
std::string GetGroupName(void) const
Get the group name.
Definition: type-id.cc:960
struct TypeId::AttributeInformation GetAttribute(uint32_t i) const
Get Attribute information by index.
Definition: type-id.cc:1075
Debug message logging.
a unique identifier for an interface.
Definition: type-id.h:58
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...
std::string help
Attribute help string.
Definition: type-id.h:80