A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
command-line.cc
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 <cstdlib> // for exit
22 
23 #include "command-line.h"
24 #include "log.h"
25 #include "config.h"
26 #include "global-value.h"
27 #include "type-id.h"
28 #include "string.h"
29 
30 
31 NS_LOG_COMPONENT_DEFINE ("CommandLine");
32 
33 namespace ns3 {
34 
35 CommandLine::CommandLine ()
36 {
37  NS_LOG_FUNCTION (this);
38 }
39 CommandLine::CommandLine (const CommandLine &cmd)
40 {
41  Copy (cmd);
42 }
43 CommandLine &
44 CommandLine::operator = (const CommandLine &cmd)
45 {
46  Clear ();
47  Copy (cmd);
48  return *this;
49 }
50 CommandLine::~CommandLine ()
51 {
52  NS_LOG_FUNCTION (this);
53  Clear ();
54 }
55 void
56 CommandLine::Copy (const CommandLine &cmd)
57 {
58  NS_LOG_FUNCTION (&cmd);
59 
60  for (Items::const_iterator i = cmd.m_items.begin ();
61  i != cmd.m_items.end (); ++i)
62  {
63  m_items.push_back (*i);
64  }
65 }
66 void
67 CommandLine::Clear (void)
68 {
69  NS_LOG_FUNCTION (this);
70 
71  for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
72  {
73  delete *i;
74  }
75  m_items.clear ();
76 }
77 
78 CommandLine::Item::~Item ()
79 {
80  NS_LOG_FUNCTION (this);
81 }
82 
83 void
84 CommandLine::Parse (int iargc, char *argv[]) const
85 {
86  NS_LOG_FUNCTION (this << iargc << argv);
87 
88  int argc = iargc;
89  for (argc--, argv++; argc > 0; argc--, argv++)
90  {
91  // remove "--" or "-" heading.
92  std::string param = *argv;
93  std::string::size_type cur = param.find ("--");
94  if (cur == 0)
95  {
96  param = param.substr (2, param.size () - 2);
97  }
98  else
99  {
100  cur = param.find ("-");
101  if (cur == 0)
102  {
103  param = param.substr (1, param.size () - 1);
104  }
105  else
106  {
107  // invalid argument. ignore.
108  continue;
109  }
110  }
111  cur = param.find ("=");
112  std::string name, value;
113  if (cur == std::string::npos)
114  {
115  name = param;
116  value = "";
117  }
118  else
119  {
120  name = param.substr (0, cur);
121  value = param.substr (cur + 1, param.size () - (cur+1));
122  }
123  HandleArgument (name, value);
124  }
125 }
126 
127 void
128 CommandLine::PrintHelp (void) const
129 {
130  NS_LOG_FUNCTION (this);
131 
132  std::cout << "--PrintHelp: Print this help message." << std::endl;
133  std::cout << "--PrintGroups: Print the list of groups." << std::endl;
134  std::cout << "--PrintTypeIds: Print all TypeIds." << std::endl;
135  std::cout << "--PrintGroup=[group]: Print all TypeIds of group." << std::endl;
136  std::cout << "--PrintAttributes=[typeid]: Print all attributes of typeid." << std::endl;
137  std::cout << "--PrintGlobals: Print the list of globals." << std::endl;
138  if (!m_items.empty ())
139  {
140  std::cout << "User Arguments:" << std::endl;
141  for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
142  {
143  std::cout << " --" << (*i)->m_name << ": " << (*i)->m_help << std::endl;
144  }
145  }
146 }
147 
148 void
149 CommandLine::PrintGlobals (void) const
150 {
151  NS_LOG_FUNCTION (this);
152 
153  for (GlobalValue::Iterator i = GlobalValue::Begin (); i != GlobalValue::End (); ++i)
154  {
155  std::cout << " --" << (*i)->GetName () << "=[";
156  Ptr<const AttributeChecker> checker = (*i)->GetChecker ();
157  StringValue v;
158  (*i)->GetValue (v);
159  std::cout << v.Get () << "]: "
160  << (*i)->GetHelp () << std::endl;
161  }
162 }
163 
164 void
165 CommandLine::PrintAttributes (std::string type) const
166 {
167  NS_LOG_FUNCTION (this);
168 
169  TypeId tid;
170  if (!TypeId::LookupByNameFailSafe (type, &tid))
171  {
172  NS_FATAL_ERROR ("Unknown type="<<type<<" in --PrintAttributes");
173  }
174  for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
175  {
176  std::cout << " --"<<tid.GetAttributeFullName (i)<<"=[";
177  struct TypeId::AttributeInformation info = tid.GetAttribute (i);
178  std::cout << info.initialValue->SerializeToString (info.checker) << "]: "
179  << info.help << std::endl;
180  }
181 }
182 
183 
184 void
185 CommandLine::PrintGroup (std::string group) const
186 {
187  NS_LOG_FUNCTION (this);
188 
189  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
190  {
191  TypeId tid = TypeId::GetRegistered (i);
192  if (tid.GetGroupName () == group)
193  {
194  std::cout << " --PrintAttributes=" <<tid.GetName ()<<std::endl;
195  }
196  }
197 }
198 
199 void
200 CommandLine::PrintTypeIds (void) const
201 {
202  NS_LOG_FUNCTION (this);
203 
204  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
205  {
206  TypeId tid = TypeId::GetRegistered (i);
207  std::cout << " --PrintAttributes=" <<tid.GetName ()<<std::endl;
208  }
209 }
210 
211 void
212 CommandLine::PrintGroups (void) const
213 {
214  NS_LOG_FUNCTION (this);
215 
216  std::list<std::string> groups;
217  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
218  {
219  TypeId tid = TypeId::GetRegistered (i);
220  std::string group = tid.GetGroupName ();
221  if (group == "")
222  {
223  continue;
224  }
225  bool found = false;
226  for (std::list<std::string>::const_iterator j = groups.begin (); j != groups.end (); ++j)
227  {
228  if (*j == group)
229  {
230  found = true;
231  break;
232  }
233  }
234  if (!found)
235  {
236  groups.push_back (group);
237  }
238  }
239  for (std::list<std::string>::const_iterator k = groups.begin (); k != groups.end (); ++k)
240  {
241  std::cout << " --PrintGroup="<<*k<<std::endl;
242  }
243 }
244 
245 void
246 CommandLine::HandleArgument (std::string name, std::string value) const
247 {
248  NS_LOG_FUNCTION (this << name << value);
249 
250  NS_LOG_DEBUG ("Handle arg name="<<name<<" value="<<value);
251  if (name == "PrintHelp")
252  {
253  // method below never returns.
254  PrintHelp ();
255  std::exit (0);
256  }
257  else if (name == "PrintGroups")
258  {
259  // method below never returns.
260  PrintGroups ();
261  std::exit (0);
262  }
263  else if (name == "PrintTypeIds")
264  {
265  // method below never returns.
266  PrintTypeIds ();
267  std::exit (0);
268  }
269  else if (name == "PrintGlobals")
270  {
271  // method below never returns.
272  PrintGlobals ();
273  std::exit (0);
274  }
275  else if (name == "PrintGroup")
276  {
277  // method below never returns.
278  PrintGroup (value);
279  std::exit (0);
280  }
281  else if (name == "PrintAttributes")
282  {
283  // method below never returns.
284  PrintAttributes (value);
285  std::exit (0);
286  }
287  else
288  {
289  for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
290  {
291  if ((*i)->m_name == name)
292  {
293  if (!(*i)->Parse (value))
294  {
295  std::cerr << "Invalid argument value: "<<name<<"="<<value << std::endl;
296  std::exit (1);
297  }
298  else
299  {
300  return;
301  }
302  }
303  }
304  }
305  if (!Config::SetGlobalFailSafe (name, StringValue (value))
306  && !Config::SetDefaultFailSafe (name, StringValue (value)))
307  {
308  std::cerr << "Invalid command-line arguments: --"<<name<<"="<<value<<std::endl;
309  PrintHelp ();
310  std::exit (1);
311  }
312 }
313 
314 bool
315 CommandLine::CallbackItem::Parse (std::string value)
316 {
317  NS_LOG_FUNCTION (this);
318  NS_LOG_DEBUG ("CommandLine::CallbackItem::Parse \"" << value << "\"");
319  return m_callback (value);
320 }
321 
322 void
323 CommandLine::AddValue (const std::string &name,
324  const std::string &help,
326 {
327  NS_LOG_FUNCTION (this << &name << &help << &callback);
328  CallbackItem *item = new CallbackItem ();
329  item->m_name = name;
330  item->m_help = help;
331  item->m_callback = callback;
332  m_items.push_back (item);
333 }
334 
335 } // namespace ns3
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
bool SetDefaultFailSafe(std::string fullName, const AttributeValue &value)
Definition: config.cc:675
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
static bool LookupByNameFailSafe(std::string name, TypeId *tid)
Definition: type-id.cc:423
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
static uint32_t GetRegisteredN(void)
Definition: type-id.cc:436
static Iterator Begin(void)
static TypeId GetRegistered(uint32_t i)
Definition: type-id.cc:442
bool SetGlobalFailSafe(std::string name, const AttributeValue &value)
Definition: config.cc:712
void AddValue(const std::string &name, const std::string &help, T &value)
Definition: command-line.h:134
static Iterator End(void)
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
void Parse(int argc, char *argv[]) const
Definition: command-line.cc:84