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  int iargc = argc;
120  for (iargc--; iargc > 0; iargc--)
121  {
122  // remove "--" or "-" heading.
123  std::string param = argv[iargc];
124  std::string::size_type cur = param.find ("--");
125  if (cur == 0)
126  {
127  param = param.substr (2, param.size () - 2);
128  }
129  else
130  {
131  cur = param.find ("-");
132  if (cur == 0)
133  {
134  param = param.substr (1, param.size () - 1);
135  }
136  else
137  {
138  // invalid argument. ignore.
139  continue;
140  }
141  }
142  cur = param.find ("=");
143  std::string name, value;
144  if (cur == std::string::npos)
145  {
146  name = param;
147  value = "";
148  }
149  else
150  {
151  name = param.substr (0, cur);
152  value = param.substr (cur + 1, param.size () - (cur+1));
153  }
154  HandleArgument (name, value);
155  }
156 
157 #ifdef ENABLE_DES_METRICS
158  DesMetrics::Get ()->Initialize (argc, argv);
159 #endif
160 
161 }
162 
163 void
164 CommandLine::PrintHelp (std::ostream &os) const
165 {
166  NS_LOG_FUNCTION (this);
167 
168  os << m_name << " [Program Arguments] [General Arguments]"
169  << std::endl;
170 
171  if (m_usage.length ())
172  {
173  os << std::endl;
174  os << m_usage << std::endl;
175  }
176 
177  if (!m_items.empty ())
178  {
179  size_t width = 0;
180  for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
181  {
182  width = std::max (width, (*i)->m_name.size ());
183  }
184  width += 3;
185 
186  os << std::endl;
187  os << "Program Arguments:" << std::endl;
188  for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
189  {
190  os << " --"
191  << std::left << std::setw (width) << ( (*i)->m_name + ":")
192  << std::right
193  << (*i)->m_help;
194 
195  if ( (*i)->HasDefault ())
196  {
197  os << " [" << (*i)->GetDefault () << "]";
198  }
199  os << std::endl;
200  }
201  }
202 
203  os << std::endl;
204  os
205  << "General Arguments:\n"
206  << " --PrintGlobals: Print the list of globals.\n"
207  << " --PrintGroups: Print the list of groups.\n"
208  << " --PrintGroup=[group]: Print all TypeIds of group.\n"
209  << " --PrintTypeIds: Print all TypeIds.\n"
210  << " --PrintAttributes=[typeid]: Print all attributes of typeid.\n"
211  << " --PrintHelp: Print this help message.\n"
212  << std::endl;
213 }
214 
215 void
216 CommandLine::PrintGlobals (std::ostream &os) const
217 {
218  NS_LOG_FUNCTION (this);
219 
220  os << "Global values:" << std::endl;
221 
222  // Sort output
223  std::vector<std::string> globals;
224 
226  i != GlobalValue::End ();
227  ++i)
228  {
229  std::stringstream ss;
230  ss << " --" << (*i)->GetName () << "=[";
231  Ptr<const AttributeChecker> checker = (*i)->GetChecker ();
232  StringValue v;
233  (*i)->GetValue (v);
234  ss << v.Get () << "]" << std::endl;
235  ss << " " << (*i)->GetHelp () << std::endl;
236  globals.push_back (ss.str ());
237  }
238  std::sort (globals.begin (), globals.end ());
239  for (std::vector<std::string>::const_iterator it = globals.begin ();
240  it < globals.end ();
241  ++it)
242  {
243  os << *it;
244  }
245 }
246 
247 void
248 CommandLine::PrintAttributes (std::ostream &os, const std::string &type) const
249 {
250  NS_LOG_FUNCTION (this);
251 
252  TypeId tid;
253  if (!TypeId::LookupByNameFailSafe (type, &tid))
254  {
255  NS_FATAL_ERROR ("Unknown type=" << type << " in --PrintAttributes");
256  }
257 
258  os << "Attributes for TypeId " << tid.GetName () << std::endl;
259 
260  // Sort output
261  std::vector<std::string> attributes;
262 
263  for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
264  {
265  std::stringstream ss;
266  ss << " --" << tid.GetAttributeFullName (i) << "=[";
267  struct TypeId::AttributeInformation info = tid.GetAttribute (i);
268  ss << info.initialValue->SerializeToString (info.checker) << "]"
269  << std::endl;
270  ss << " " << info.help << std::endl;
271  attributes.push_back (ss.str ());
272  }
273  std::sort (attributes.begin (), attributes.end ());
274  for (std::vector<std::string>::const_iterator it = attributes.begin ();
275  it < attributes.end ();
276  ++it)
277  {
278  os << *it;
279  }
280 }
281 
282 
283 void
284 CommandLine::PrintGroup (std::ostream &os, const std::string &group) const
285 {
286  NS_LOG_FUNCTION (this);
287 
288  os << "TypeIds in group " << group << ":" << std::endl;
289 
290  // Sort output
291  std::vector<std::string> groupTypes;
292 
293  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
294  {
295  std::stringstream ss;
296  TypeId tid = TypeId::GetRegistered (i);
297  if (tid.GetGroupName () == group)
298  {
299  ss << " " <<tid.GetName () << std::endl;
300  }
301  groupTypes.push_back (ss.str ());
302  }
303  std::sort (groupTypes.begin (), groupTypes.end ());
304  for (std::vector<std::string>::const_iterator it = groupTypes.begin ();
305  it < groupTypes.end ();
306  ++it)
307  {
308  os << *it;
309  }
310 }
311 
312 void
313 CommandLine::PrintTypeIds (std::ostream &os) const
314 {
315  NS_LOG_FUNCTION (this);
316  os << "Registered TypeIds:" << std::endl;
317 
318  // Sort output
319  std::vector<std::string> types;
320 
321  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
322  {
323  std::stringstream ss;
324  TypeId tid = TypeId::GetRegistered (i);
325  ss << " " << tid.GetName () << std::endl;
326  types.push_back (ss.str ());
327  }
328  std::sort (types.begin (), types.end ());
329  for (std::vector<std::string>::const_iterator it = types.begin ();
330  it < types.end ();
331  ++it)
332  {
333  os << *it;
334  }
335 }
336 
337 void
338 CommandLine::PrintGroups (std::ostream &os) const
339 {
340  NS_LOG_FUNCTION (this);
341 
342  std::set<std::string> groups;
343  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
344  {
345  TypeId tid = TypeId::GetRegistered (i);
346  groups.insert (tid.GetGroupName ());
347  }
348 
349  os << "Registered TypeId groups:" << std::endl;
350  // Sets are already sorted
351  for (std::set<std::string>::const_iterator k = groups.begin ();
352  k != groups.end ();
353  ++k)
354  {
355  os << " " << *k << std::endl;
356  }
357 }
358 
359 void
360 CommandLine::HandleArgument (const std::string &name, const std::string &value) const
361 {
362  NS_LOG_FUNCTION (this << name << value);
363 
364  NS_LOG_DEBUG ("Handle arg name=" << name << " value=" << value);
365  if (name == "PrintHelp" || name == "help")
366  {
367  // method below never returns.
368  PrintHelp (std::cout);
369  std::exit (0);
370  }
371  else if (name == "PrintGroups")
372  {
373  // method below never returns.
374  PrintGroups (std::cout);
375  std::exit (0);
376  }
377  else if (name == "PrintTypeIds")
378  {
379  // method below never returns.
380  PrintTypeIds (std::cout);
381  std::exit (0);
382  }
383  else if (name == "PrintGlobals")
384  {
385  // method below never returns.
386  PrintGlobals (std::cout);
387  std::exit (0);
388  }
389  else if (name == "PrintGroup")
390  {
391  // method below never returns.
392  PrintGroup (std::cout, value);
393  std::exit (0);
394  }
395  else if (name == "PrintAttributes")
396  {
397  // method below never returns.
398  PrintAttributes (std::cout, value);
399  std::exit (0);
400  }
401  else
402  {
403  for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
404  {
405  if ((*i)->m_name == name)
406  {
407  if (!(*i)->Parse (value))
408  {
409  std::cerr << "Invalid argument value: "
410  << name << "=" << value << std::endl;
411  std::exit (1);
412  }
413  else
414  {
415  return;
416  }
417  }
418  }
419  }
420  if (!Config::SetGlobalFailSafe (name, StringValue (value))
421  && !Config::SetDefaultFailSafe (name, StringValue (value)))
422  {
423  std::cerr << "Invalid command-line arguments: --"
424  << name << "=" << value << std::endl;
425  PrintHelp (std::cerr);
426  std::exit (1);
427  }
428 }
429 
430 bool
431 CommandLine::CallbackItem::Parse (const std::string value)
432 {
433  NS_LOG_FUNCTION (this);
434  NS_LOG_DEBUG ("CommandLine::CallbackItem::Parse \"" << value << "\"");
435  return m_callback (value);
436 }
437 
438 void
439 CommandLine::AddValue (const std::string &name,
440  const std::string &help,
442 {
443  NS_LOG_FUNCTION (this << &name << &help << &callback);
444  CallbackItem *item = new CallbackItem ();
445  item->m_name = name;
446  item->m_help = help;
447  item->m_callback = callback;
448  m_items.push_back (item);
449 }
450 
451 void
452 CommandLine::AddValue (const std::string &name,
453  const std::string &attributePath)
454 {
455  NS_LOG_FUNCTION (this << name << attributePath);
456  // Attribute name is last token
457  size_t colon = attributePath.rfind ("::");
458  const std::string typeName = attributePath.substr (0, colon);
459  NS_LOG_DEBUG ("typeName: '" << typeName << "', colon: " << colon);
460 
461  TypeId tid;
462  if (!TypeId::LookupByNameFailSafe (typeName, &tid))
463  {
464  NS_FATAL_ERROR ("Unknown type=" << typeName);
465  }
466 
467  const std::string attrName = attributePath.substr (colon + 2);
468  struct TypeId::AttributeInformation info;
469  if (!tid.LookupAttributeByName (attrName, &info))
470  {
471  NS_FATAL_ERROR ("Attribute not found: " << attributePath);
472  }
473 
474  std::stringstream ss;
475  ss << info.help
476  << " (" << attributePath << ") ["
477  << info.initialValue->SerializeToString (info.checker) << "]";
478 
479  AddValue (name, ss.str (),
481 }
482 
483 
484 /* static */
485 bool
486 CommandLine::HandleAttribute (const std::string name,
487  const std::string value)
488 {
489  bool success = true;
490  if (!Config::SetGlobalFailSafe (name, StringValue (value))
491  && !Config::SetDefaultFailSafe (name, StringValue (value)))
492  {
493  success = false;
494  }
495  return success;
496 }
497 
498 
499 bool
501 {
502  return false;
503 }
504 
505 std::string
507 {
508  return "";
509 }
510 
511 template <>
512 std::string
514 {
515  std::ostringstream oss;
516  oss << std::boolalpha << val;
517  return oss.str ();
518 }
519 
520 template <>
521 bool
522 CommandLineHelper::UserItemParse<bool> (const std::string value, bool & val)
523 {
524  std::string src = value;
525  std::transform(src.begin(), src.end(), src.begin(), ::tolower);
526 
527  if (src.length () == 0)
528  {
529  val = ! val;
530  return true;
531  }
532  else if ( (src == "true") || (src == "t") )
533  {
534  val = true;
535  return true;
536  }
537  else if ( (src == "false") || (src == "f"))
538  {
539  val = false;
540  return true;
541  }
542  else
543  {
544  std::istringstream iss;
545  iss.str (src);
546  iss >> val;
547  return !iss.bad () && !iss.fail ();
548  }
549 }
550 
551 std::ostream &
552 operator << (std::ostream & os, const CommandLine & cmd)
553 {
554  cmd.PrintHelp (os);
555  return os;
556 }
557 
558 } // namespace ns3
~CommandLine()
Destructor.
Definition: command-line.cc:63
uint32_t GetAttributeN(void) const
Get the number of attributes.
Definition: type-id.cc:1058
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:782
std::string Get(void) const
Definition: string.cc:31
Items m_items
The list of arguments.
Definition: command-line.h:436
Hold variables of type string.
Definition: string.h:41
String attribute value declarations.
bool SetGlobalFailSafe(std::string name, const AttributeValue &value)
Definition: config.cc:819
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:77
#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:821
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:204
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
System-independent file and directory function 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:437
#define max(a, b)
Definition: 80211b.c:45
static uint32_t GetRegisteredN(void)
Get the number of registered TypeIds.
Definition: type-id.cc:853
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:859
std::string m_name
The program name.
Definition: command-line.h:438
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.
CommandLine class 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:866
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:958
ns3::GlobalValue declaration.
virtual bool HasDefault() const
virtual ~Item()
Destructor.
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:495
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:236
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:1071
void Parse(int argc, char *argv[])
Parse the program arguments.
std::string GetGroupName(void) const
Get the group name.
Definition: type-id.cc:950
struct TypeId::AttributeInformation GetAttribute(uint32_t i) const
Get Attribute information by index.
Definition: type-id.cc:1065
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