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