A Discrete-Event Network Simulator
API
command-line.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008 INRIA
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18 */
19
20#include "command-line.h"
21
22#include "config.h"
23#include "des-metrics.h"
24#include "global-value.h"
25#include "log.h"
26#include "string.h"
27#include "system-path.h"
28#include "type-id.h"
29
30#if defined(ENABLE_BUILD_VERSION)
31#include "version.h"
32#endif
33
34#include <algorithm> // transform
35#include <cctype> // tolower
36#include <cstdlib> // exit, getenv
37#include <cstring> // strlen
38#include <iomanip> // setw, boolalpha
39#include <set>
40#include <sstream>
41
49namespace
50{
59std::string
60Encode(const std::string& source)
61{
62 std::string buffer;
63 buffer.reserve(1.1 * source.size());
64
65 for (size_t pos = 0; pos != source.size(); ++pos)
66 {
67 switch (source[pos])
68 {
69 case '&':
70 buffer.append("&amp;");
71 break;
72 case '\"':
73 buffer.append("&quot;");
74 break;
75 case '\'':
76 buffer.append("&apos;");
77 break;
78 // case '>': buffer.append ("&gt;"); break;
79
80 case '<':
81 // Special case:
82 // "...blah <file..." is not allowed
83 // "...foo<bar..." is allowed
84 if (buffer.empty() || buffer.back() == ' ')
85 {
86 buffer.append("&lt;");
87 }
88 else
89 {
90 buffer.append("<");
91 }
92
93 break;
94
95 default:
96 buffer.append(&source[pos], 1);
97 break;
98 }
99 }
100 return buffer;
101}
102
103} // anonymous namespace
104
105namespace ns3
106{
107
108NS_LOG_COMPONENT_DEFINE("CommandLine");
109
111 : m_NNonOptions(0),
112 m_nonOptionCount(0),
113 m_usage(),
114 m_shortName()
115{
116 NS_LOG_FUNCTION(this);
117}
118
119CommandLine::CommandLine(const std::string& filename)
120 : m_NNonOptions(0),
121 m_nonOptionCount(0),
122 m_usage()
123{
124 NS_LOG_FUNCTION(this << filename);
125 std::string basename = SystemPath::Split(filename).back();
126 m_shortName = basename.substr(0, basename.rfind(".cc"));
127 m_shortName = m_shortName.substr(basename.find_last_of('/') + 1);
128}
129
131{
132 Copy(cmd);
133}
134
137{
138 Clear();
139 Copy(cmd);
140 return *this;
141}
142
144{
145 NS_LOG_FUNCTION(this);
146 Clear();
147}
148
149void
151{
153
154 std::copy(cmd.m_options.begin(), cmd.m_options.end(), m_options.end());
155 std::copy(cmd.m_nonOptions.begin(), cmd.m_nonOptions.end(), m_nonOptions.end());
156
157 m_NNonOptions = cmd.m_NNonOptions;
159 m_usage = cmd.m_usage;
160 m_shortName = cmd.m_shortName;
161}
162
163void
165{
166 NS_LOG_FUNCTION(this);
167
168 m_options.clear();
169 m_nonOptions.clear();
170 m_NNonOptions = 0;
171 m_usage = "";
172 m_shortName = "";
173}
174
175void
176CommandLine::Usage(const std::string& usage)
177{
178 m_usage = usage;
179}
180
181std::string
183{
184 return m_shortName;
185}
186
188{
189 NS_LOG_FUNCTION(this);
190}
191
192void
193CommandLine::Parse(std::vector<std::string> args)
194{
195 NS_LOG_FUNCTION(this << args.size() << args);
196
198
200
201 if (args.size() > 0)
202 {
203 args.erase(args.begin()); // discard the program name
204
206
207 for (const auto& param : args)
208 {
209 if (HandleOption(param))
210 {
211 continue;
212 }
213 if (HandleNonOption(param))
214 {
215 continue;
216 }
217
218 // is this possible?
219 NS_ASSERT_MSG(false,
220 "unexpected error parsing command line parameter: '" << param << "'");
221 }
222 }
223
224#ifdef ENABLE_DES_METRICS
226#endif
227}
228
230CommandLine::GetOptionName(const std::string& param) const
231{
232 // remove leading "--" or "-"
233 std::string arg = param;
234 std::string::size_type cur = arg.find("--");
235 if (cur == 0)
236 {
237 arg = arg.substr(2, arg.size() - 2);
238 }
239 else
240 {
241 cur = arg.find('-');
242 if (cur == 0)
243 {
244 arg = arg.substr(1, arg.size() - 1);
245 }
246 else
247 {
248 // non-option argument?
249 return {false, param, ""};
250 }
251 }
252
253 // find any value following '='
254 cur = arg.find('=');
255 std::string name;
256 std::string value;
257 if (cur == std::string::npos)
258 {
259 name = arg;
260 value = "";
261 }
262 else
263 {
264 name = arg.substr(0, cur);
265 value = arg.substr(cur + 1, arg.size() - (cur + 1));
266 }
267
268 return {true, name, value};
269}
270
271void
272CommandLine::HandleHardOptions(const std::vector<std::string>& args) const
273{
274 NS_LOG_FUNCTION(this << args.size() << args);
275
276 for (const auto& param : args)
277 {
278 auto [isOpt, name, value] = GetOptionName(param);
279 if (!isOpt)
280 {
281 continue;
282 }
283
284 // Hard-coded options
285 if (name == "PrintHelp" || name == "help")
286 {
287 // method below never returns.
288 PrintHelp(std::cout);
289 std::exit(0);
290 }
291 if (name == "PrintVersion" || name == "version")
292 {
293 // Print the version, then exit the program
294 PrintVersion(std::cout);
295 std::exit(0);
296 }
297 else if (name == "PrintGroups")
298 {
299 // method below never returns.
300 PrintGroups(std::cout);
301 std::exit(0);
302 }
303 else if (name == "PrintTypeIds")
304 {
305 // method below never returns.
306 PrintTypeIds(std::cout);
307 std::exit(0);
308 }
309 else if (name == "PrintGlobals")
310 {
311 // method below never returns.
312 PrintGlobals(std::cout);
313 std::exit(0);
314 }
315 else if (name == "PrintGroup")
316 {
317 // method below never returns.
318 PrintGroup(std::cout, value);
319 std::exit(0);
320 }
321 else if (name == "PrintAttributes")
322 {
323 // method below never returns.
324 PrintAttributes(std::cout, value);
325 std::exit(0);
326 }
327 }
328}
329
330bool
331CommandLine::HandleOption(const std::string& param) const
332{
333 auto [isOpt, name, value] = GetOptionName(param);
334 if (!isOpt)
335 {
336 return false;
337 }
338
339 HandleArgument(name, value);
340
341 return true;
342}
343
344bool
346{
347 NS_LOG_FUNCTION(this << value);
348
349 if (m_nonOptionCount == m_nonOptions.size())
350 {
351 // Add an unspecified non-option as a string
352 NS_LOG_LOGIC("adding StringItem, NOCount:" << m_nonOptionCount
353 << ", NOSize:" << m_nonOptions.size());
354 auto item = std::make_shared<StringItem>();
355 item->m_name = "extra-non-option-argument";
356 item->m_help = "Extra non-option argument encountered.";
357 item->m_value = value;
358 m_nonOptions.push_back(item);
359 }
360
362 if (!i->Parse(value))
363 {
364 std::cerr << "Invalid non-option argument value " << value << " for " << i->m_name
365 << std::endl;
366 PrintHelp(std::cerr);
367 std::exit(1);
368 }
370 return true;
371}
372
373void
374CommandLine::Parse(int argc, char* argv[])
375{
376 NS_LOG_FUNCTION(this << argc);
377 std::vector<std::string> args(argv, argv + argc);
378 Parse(args);
379}
380
381void
382CommandLine::PrintHelp(std::ostream& os) const
383{
384 NS_LOG_FUNCTION(this);
385
386 // Hack to show just the declared non-options
387 Items nonOptions(m_nonOptions.begin(), m_nonOptions.begin() + m_NNonOptions);
388 os << m_shortName << (m_options.size() ? " [Program Options]" : "")
389 << (nonOptions.size() ? " [Program Arguments]" : "") << " [General Arguments]" << std::endl;
390
391 if (!m_usage.empty())
392 {
393 os << std::endl;
394 os << m_usage << std::endl;
395 }
396
397 std::size_t width = 0;
398 auto max_width = [&width](const std::shared_ptr<Item> item) {
399 width = std::max(width, item->m_name.size());
400 };
401 std::for_each(m_options.begin(), m_options.end(), max_width);
402 std::for_each(nonOptions.begin(), nonOptions.end(), max_width);
403 width += 3; // room for ": " between option and help
404
405 auto optionsHelp = [&os, width](const std::string& head, bool option, const Items& items) {
406 os << "\n" << head << "\n";
407 for (const auto& item : items)
408 {
409 os << " " << (option ? "--" : " ") << std::left << std::setw(width)
410 << (item->m_name + ":") << std::right << item->m_help;
411
412 if (item->HasDefault())
413 {
414 os << " [" << item->GetDefault() << "]";
415 }
416 os << "\n";
417 }
418 };
419
420 if (!m_options.empty())
421 {
422 optionsHelp("Program Options:", true, m_options);
423 }
424
425 if (!nonOptions.empty())
426 {
427 optionsHelp("Program Arguments:", false, nonOptions);
428 }
429
430 os << std::endl;
431 os << "General Arguments:\n"
432 << " --PrintGlobals: Print the list of globals.\n"
433 << " --PrintGroups: Print the list of groups.\n"
434 << " --PrintGroup=[group]: Print all TypeIds of group.\n"
435 << " --PrintTypeIds: Print all TypeIds.\n"
436 << " --PrintAttributes=[typeid]: Print all attributes of typeid.\n"
437 << " --PrintVersion: Print the ns-3 version.\n"
438 << " --PrintHelp: Print this help message.\n"
439 << std::endl;
440}
441
442std::string
444{
445#if defined(ENABLE_BUILD_VERSION)
446 return Version::LongVersion();
447#else
448 return std::string{"Build version support is not enabled, reconfigure with "
449 "--enable-build-version flag"};
450#endif
451}
452
453void
454CommandLine::PrintVersion(std::ostream& os) const
455{
456 os << GetVersion() << std::endl;
457}
458
459void
461{
462 NS_LOG_FUNCTION(this);
463
464 const char* envVar = std::getenv("NS_COMMANDLINE_INTROSPECTION");
465 if (envVar == nullptr || std::strlen(envVar) == 0)
466 {
467 return;
468 }
469
470 if (m_shortName.size() == 0)
471 {
472 NS_FATAL_ERROR("No file name on example-to-run; forgot to use CommandLine var (__FILE__)?");
473 return;
474 }
475
476 // Hack to show just the declared non-options
477 Items nonOptions(m_nonOptions.begin(), m_nonOptions.begin() + m_NNonOptions);
478
479 std::string outf = SystemPath::Append(std::string(envVar), m_shortName + ".command-line");
480
481 NS_LOG_INFO("Writing CommandLine doxy to " << outf);
482
483 std::fstream os(outf, std::fstream::out);
484
485 os << "/**\n \\file " << m_shortName << ".cc\n"
486 << "<h3>Usage</h3>\n"
487 << "<code>$ ./ns3 run \"" << m_shortName << (m_options.size() ? " [Program Options]" : "")
488 << (nonOptions.size() ? " [Program Arguments]" : "") << "\"</code>\n";
489
490 if (!m_usage.empty())
491 {
492 os << Encode(m_usage) << "\n";
493 }
494
495 auto listOptions = [&os](const std::string& head, const Items& items, std::string pre) {
496 os << "\n<h3>" << head << "</h3>\n<dl>\n";
497 for (const auto& i : items)
498 {
499 os << " <dt>" << pre << i->m_name << " </dt>\n"
500 << " <dd>" << Encode(i->m_help);
501
502 if (i->HasDefault())
503 {
504 os << " [" << Encode(i->GetDefault()) << "]";
505 }
506 os << " </dd>\n";
507 }
508 os << "</dl>\n";
509 };
510
511 if (!m_options.empty())
512 {
513 listOptions("Program Options", m_options, "\\c --");
514 }
515
516 if (!nonOptions.empty())
517 {
518 listOptions("Program Arguments", nonOptions, "\\c ");
519 }
520
521 os << "*/" << std::endl;
522
523 // All done, don't need to actually run the example
524 os.close();
525 std::exit(0);
526}
527
528void
529CommandLine::PrintGlobals(std::ostream& os) const
530{
531 NS_LOG_FUNCTION(this);
532
533 os << "Global values:" << std::endl;
534
535 // Sort output
536 std::vector<std::string> globals;
537
538 for (auto i = GlobalValue::Begin(); i != GlobalValue::End(); ++i)
539 {
540 std::stringstream ss;
541 ss << " --" << (*i)->GetName() << "=[";
542 Ptr<const AttributeChecker> checker = (*i)->GetChecker();
543 StringValue v;
544 (*i)->GetValue(v);
545 ss << v.Get() << "]" << std::endl;
546 ss << " " << (*i)->GetHelp() << std::endl;
547 globals.push_back(ss.str());
548 }
549 std::sort(globals.begin(), globals.end());
550 for (const auto& s : globals)
551 {
552 os << s;
553 }
554}
555
556void
557CommandLine::PrintAttributeList(std::ostream& os, const TypeId tid, std::stringstream& header) const
558{
559 NS_LOG_FUNCTION(this);
560
561 if (!tid.GetAttributeN())
562 {
563 return;
564 }
565 os << header.str() << "\n";
566 // To sort output
567 std::vector<std::string> attributes;
568
569 for (uint32_t i = 0; i < tid.GetAttributeN(); ++i)
570 {
571 std::stringstream ss;
572 ss << " --" << tid.GetAttributeFullName(i) << "=[";
573 struct TypeId::AttributeInformation info = tid.GetAttribute(i);
574 ss << info.initialValue->SerializeToString(info.checker) << "]\n"
575 << " " << info.help << "\n";
576 attributes.push_back(ss.str());
577 }
578 std::sort(attributes.begin(), attributes.end());
579 for (const auto& s : attributes)
580 {
581 os << s;
582 }
583}
584
585void
586CommandLine::PrintAttributes(std::ostream& os, const std::string& type) const
587{
588 NS_LOG_FUNCTION(this);
589
590 TypeId tid;
592 {
593 NS_FATAL_ERROR("Unknown type=" << type << " in --PrintAttributes");
594 }
595
596 std::stringstream header;
597 header << "Attributes for TypeId " << tid.GetName();
598 PrintAttributeList(os, tid, header);
599 header.str("");
600
601 // Parent Attributes
602 if (tid.GetParent() != tid)
603 {
604 TypeId tmp = tid.GetParent();
605 while (tmp.GetParent() != tmp)
606 {
607 header << "Attributes defined in parent class " << tmp.GetName();
608 PrintAttributeList(os, tmp, header);
609 header.str("");
610 tmp = tmp.GetParent();
611 }
612 }
613}
614
615void
616CommandLine::PrintGroup(std::ostream& os, const std::string& group) const
617{
618 NS_LOG_FUNCTION(this);
619
620 os << "TypeIds in group " << group << ":" << std::endl;
621
622 // Sort output
623 std::vector<std::string> groupTypes;
624
625 for (uint16_t i = 0; i < TypeId::GetRegisteredN(); ++i)
626 {
627 std::stringstream ss;
629 if (tid.GetGroupName() == group)
630 {
631 ss << " " << tid.GetName() << std::endl;
632 }
633 groupTypes.push_back(ss.str());
634 }
635 std::sort(groupTypes.begin(), groupTypes.end());
636 for (const auto& s : groupTypes)
637 {
638 os << s;
639 }
640}
641
642void
643CommandLine::PrintTypeIds(std::ostream& os) const
644{
645 NS_LOG_FUNCTION(this);
646 os << "Registered TypeIds:" << std::endl;
647
648 // Sort output
649 std::vector<std::string> types;
650
651 for (uint16_t i = 0; i < TypeId::GetRegisteredN(); ++i)
652 {
653 std::stringstream ss;
655 ss << " " << tid.GetName() << std::endl;
656 types.push_back(ss.str());
657 }
658 std::sort(types.begin(), types.end());
659 for (const auto& s : types)
660 {
661 os << s;
662 }
663}
664
665void
666CommandLine::PrintGroups(std::ostream& os) const
667{
668 NS_LOG_FUNCTION(this);
669
670 std::set<std::string> groups;
671 for (uint16_t i = 0; i < TypeId::GetRegisteredN(); ++i)
672 {
674 groups.insert(tid.GetGroupName());
675 }
676
677 os << "Registered TypeId groups:" << std::endl;
678 // Sets are already sorted
679 for (const auto& s : groups)
680 {
681 os << " " << s << std::endl;
682 }
683}
684
685bool
686CommandLine::HandleArgument(const std::string& name, const std::string& value) const
687{
688 NS_LOG_FUNCTION(this << name << value);
689
690 NS_LOG_DEBUG("Handle arg name=" << name << " value=" << value);
691
692 auto errorExit = [this, name, value]() {
693 std::cerr << "Invalid command-line argument: --" << name;
694 if (value != "")
695 {
696 std::cerr << "=" << value;
697 }
698 std::cerr << std::endl;
699 this->PrintHelp(std::cerr);
700 std::exit(1);
701 };
702
703 auto item = std::find_if(m_options.begin(), m_options.end(), [name](std::shared_ptr<Item> it) {
704 return it->m_name == name;
705 });
706 if (item != m_options.end())
707 {
708 if (!(*item)->Parse(value))
709 {
710 errorExit();
711 }
712 return true;
713 }
714
715 // Global or ConfigPath options
716 if (!HandleAttribute(name, value))
717 {
718 errorExit();
719 }
720 return true;
721}
722
723bool
725{
726 return m_default != "";
727}
728
729std::string
731{
732 return m_default;
733}
734
735bool
737{
738 NS_LOG_FUNCTION(this);
739 NS_LOG_DEBUG("CommandLine::CallbackItem::Parse \"" << value << "\"");
740 return m_callback(value);
741}
742
743void
744CommandLine::AddValue(const std::string& name,
745 const std::string& help,
746 char* value,
747 std::size_t num)
748{
749 NS_LOG_FUNCTION(this << name << help << value << num);
750 auto item = std::make_shared<CharStarItem>();
751 item->m_name = name;
752 item->m_help = help;
753 item->m_buffer = value;
754 item->m_size = num;
755 item->m_default.assign(value);
756 m_options.push_back(item);
757}
758
759void
760CommandLine::AddValue(const std::string& name,
761 const std::string& help,
763 const std::string& defaultValue /* = "" */)
764
765{
766 NS_LOG_FUNCTION(this << &name << &help << &callback);
767 auto item = std::make_shared<CallbackItem>();
768 item->m_name = name;
769 item->m_help = help;
770 item->m_callback = callback;
771 item->m_default = defaultValue;
772 m_options.push_back(item);
773}
774
775void
776CommandLine::AddValue(const std::string& name, const std::string& attributePath)
777{
778 NS_LOG_FUNCTION(this << name << attributePath);
779 // Attribute name is last token
780 std::size_t colon = attributePath.rfind("::");
781 const std::string typeName = attributePath.substr(0, colon);
782 NS_LOG_DEBUG("typeName: '" << typeName << "', colon: " << colon);
783
784 TypeId tid;
785 if (!TypeId::LookupByNameFailSafe(typeName, &tid))
786 {
787 NS_FATAL_ERROR("Unknown type=" << typeName);
788 }
789
790 const std::string attrName = attributePath.substr(colon + 2);
792 if (!tid.LookupAttributeByName(attrName, &info))
793 {
794 NS_FATAL_ERROR("Attribute not found: " << attributePath);
795 }
796
797 std::stringstream ss;
798 ss << info.help << " (" << attributePath << ") ["
799 << info.initialValue->SerializeToString(info.checker) << "]";
800
801 AddValue(name, ss.str(), MakeBoundCallback(CommandLine::HandleAttribute, attributePath));
802}
803
804std::string
806{
807 std::string value;
808
809 if (m_nonOptions.size() >= i + m_NNonOptions)
810 {
811 auto ip = std::dynamic_pointer_cast<StringItem>(m_nonOptions[i + m_NNonOptions]);
812 if (ip != nullptr)
813 {
814 value = ip->m_value;
815 }
816 }
817 return value;
818}
819
820std::size_t
822{
823 if (m_nonOptions.size() > m_NNonOptions)
824 {
825 return m_nonOptions.size() - m_NNonOptions;
826 }
827 else
828 {
829 return 0;
830 }
831}
832
833/* static */
834bool
835CommandLine::HandleAttribute(const std::string& name, const std::string& value)
836{
839}
840
841bool
843{
844 return false;
845}
846
847bool
848CommandLine::StringItem::Parse(const std::string& value) const
849{
850 m_value = value; // mutable
851 return true;
852}
853
854bool
856{
857 return false;
858}
859
860std::string
862{
863 return "";
864}
865
866bool
868{
869 if (value.size() > m_size - 1)
870 {
871 std::cerr << "Value \"" << value << "\" (" << value.size() << " bytes) is too long for "
872 << m_name << " buffer (" << m_size << " bytes, including terminating null)."
873 << std::endl;
874 return false;
875 }
876
877 std::strncpy(m_buffer, value.c_str(), m_size);
878 return true;
879}
880
881bool
883{
884 return true;
885}
886
887std::string
889{
890 return m_default;
891}
892
893template <>
894std::string
895CommandLineHelper::GetDefault<bool>(const std::string& defaultValue)
896{
897 bool value;
898 std::istringstream iss(defaultValue);
899 iss >> value;
900 std::ostringstream oss;
901 oss << std::boolalpha << value;
902 return oss.str();
903}
904
905template <>
906bool
907CommandLineHelper::UserItemParse<bool>(const std::string& value, bool& dest)
908{
909 // No new value, so just toggle it
910 if (value.empty())
911 {
912 dest = !dest;
913 return true;
914 }
915
916 std::string src = value;
917 std::transform(src.begin(), src.end(), src.begin(), [](char c) {
918 return static_cast<char>(std::tolower(c));
919 });
920 if (src == "true" || src == "t")
921 {
922 dest = true;
923 return true;
924 }
925 else if (src == "false" || src == "f")
926 {
927 dest = false;
928 return true;
929 }
930 else
931 {
932 std::istringstream iss;
933 iss.str(src);
934 iss >> dest;
935 return !iss.bad() && !iss.fail();
936 }
937}
938
939template <>
940std::string
941CommandLineHelper::GetDefault<Time>(const std::string& defaultValue)
942{
943 std::ostringstream oss;
944 oss << Time(defaultValue).As();
945 return oss.str();
946}
947
948template <>
949bool
950CommandLineHelper::UserItemParse<uint8_t>(const std::string& value, uint8_t& dest)
951{
952 uint8_t oldDest = dest;
953 int newDest;
954
955 try
956 {
957 newDest = std::stoi(value);
958 }
959 catch (std::invalid_argument& ia)
960 {
961 NS_LOG_WARN("invalid argument: " << ia.what());
962 dest = oldDest;
963 return false;
964 }
965 catch (std::out_of_range& oor)
966 {
967 NS_LOG_WARN("out of range: " << oor.what());
968 dest = oldDest;
969 return false;
970 }
971 if (newDest < 0 || newDest > 255)
972 {
973 return false;
974 }
975 dest = newDest;
976 return true;
977}
978
979std::ostream&
980operator<<(std::ostream& os, const CommandLine& cmd)
981{
982 cmd.PrintHelp(os);
983 return os;
984}
985
986} // namespace ns3
#define max(a, b)
Definition: 80211b.c:43
bool HasDefault() const override
std::string GetDefault() const override
bool Parse(const std::string &value) const override
Parse from a string.
bool Parse(const std::string &value) const override
Parse from a string.
std::string GetDefault() const override
bool HasDefault() const override
virtual ~Item()
Destructor.
virtual bool HasDefault() const
bool Parse(const std::string &value) const override
Parse from a string.
std::string GetDefault() const override
bool HasDefault() const override
Parse command-line arguments.
Definition: command-line.h:232
void PrintAttributeList(std::ostream &os, const TypeId tid, std::stringstream &header) const
Print the Attributes for a single type.
HasOptionName GetOptionName(const std::string &param) const
Strip leading -- or - from options.
std::tuple< bool, std::string, std::string > HasOptionName
Tuple type returned by GetOptionName().
Definition: command-line.h:549
void PrintGroups(std::ostream &os) const
Handler for --PrintGroups: print all TypeId group names.
void PrintTypeIds(std::ostream &os) const
Handler for --PrintTypeIds: print all TypeId names.
std::string GetExtraNonOption(std::size_t i) const
Get extra non-option arguments by index.
std::vector< std::shared_ptr< Item > > Items
Argument list container.
Definition: command-line.h:657
std::size_t m_nonOptionCount
The number of actual non-option arguments seen so far.
Definition: command-line.h:667
std::size_t GetNExtraNonOptions() const
Get the total number of non-option arguments found, including those configured with AddNonOption() an...
void PrintDoxygenUsage() const
Append usage message in Doxygen format to the file indicated by the NS_COMMANDLINE_INTROSPECTION envi...
~CommandLine()
Destructor.
std::string GetName() const
Get the program name.
Items m_options
The list of option arguments.
Definition: command-line.h:660
bool HandleNonOption(const std::string &value)
Handle a non-option.
void Parse(int argc, char *argv[])
Parse the program arguments.
void PrintGroup(std::ostream &os, const std::string &group) const
Handler for --PrintGroup: print all types belonging to a given group.
void Copy(const CommandLine &cmd)
Copy constructor implementation.
std::size_t m_NNonOptions
The expected number of non-option arguments.
Definition: command-line.h:665
void PrintGlobals(std::ostream &os) const
Handler for --PrintGlobals: print all global variables and values.
Items m_nonOptions
The list of non-option arguments.
Definition: command-line.h:662
void PrintVersion(std::ostream &os) const
Print ns-3 version to the desired output stream.
void HandleHardOptions(const std::vector< std::string > &args) const
Handle hard-coded options.
std::string m_shortName
The source file name (without .cc), as would be given to ns3 run
Definition: command-line.h:671
bool HandleOption(const std::string &param) const
Handle an option in the form param=value.
std::string m_usage
The Usage string.
Definition: command-line.h:669
void Clear()
Remove all arguments, Usage(), name.
void PrintAttributes(std::ostream &os, const std::string &type) const
Handler for --PrintAttributes: print the attributes for a given type as well as its parents.
bool HandleArgument(const std::string &name, const std::string &value) const
Match name against the program or general arguments, and dispatch to the appropriate handler.
void AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
Definition: command-line.h:746
static bool HandleAttribute(const std::string &name, const std::string &value)
Callback function to handle attributes.
CommandLine()
Constructor.
void PrintHelp(std::ostream &os) const
Print program usage to the desired output stream.
std::string GetVersion() const
Get the program version.
CommandLine & operator=(const CommandLine &cmd)
Assignment.
void Usage(const std::string &usage)
Supply the program usage and documentation.
void Initialize(std::vector< std::string > args, std::string outDir="")
Open the DesMetrics trace file and print the header.
Definition: des-metrics.cc:42
static Iterator Begin()
The Begin iterator.
static Iterator End()
The End iterator.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static DesMetrics * Get()
Get a pointer to the singleton instance.
Definition: singleton.h:100
Hold variables of type string.
Definition: string.h:42
std::string Get() const
Definition: string.cc:31
a unique identifier for an interface.
Definition: type-id.h:60
std::string GetGroupName() const
Get the group name.
Definition: type-id.cc:987
static uint16_t GetRegisteredN()
Get the number of registered TypeIds.
Definition: type-id.cc:883
std::string GetAttributeFullName(std::size_t i) const
Get the Attribute name by index.
Definition: type-id.cc:1119
struct TypeId::AttributeInformation GetAttribute(std::size_t i) const
Get Attribute information by index.
Definition: type-id.cc:1112
std::size_t GetAttributeN() const
Get the number of attributes.
Definition: type-id.cc:1104
TypeId GetParent() const
Get the parent of this TypeId.
Definition: type-id.cc:959
static TypeId GetRegistered(uint16_t i)
Get a TypeId by index.
Definition: type-id.cc:890
bool LookupAttributeByName(std::string name, struct AttributeInformation *info) const
Find an Attribute by name, retrieving the associated AttributeInformation.
Definition: type-id.cc:897
static bool LookupByNameFailSafe(std::string name, TypeId *tid)
Get a TypeId by name.
Definition: type-id.cc:848
std::string GetName() const
Get the name.
Definition: type-id.cc:995
static std::string LongVersion()
Constructs a string containing all of the build details.
Definition: version.cc:133
ns3::CommandLine declaration.
Declaration of the various ns3::Config functions and classes.
ns3::DesMetrics declaration.
ns3::GlobalValue declaration.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
std::string GetDefault< Time >(const std::string &defaultValue)
Helper to specialize CommandLine::UserItem::GetDefault() on types needing special handling.
std::string GetDefault< bool >(const std::string &defaultValue)
Helper to specialize CommandLine::UserItem::GetDefault() on types needing special handling.
bool SetGlobalFailSafe(std::string name, const AttributeValue &value)
Definition: config.cc:944
bool SetDefaultFailSafe(std::string fullName, const AttributeValue &value)
Definition: config.cc:901
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:160
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs... bargs)
Make Callbacks with varying number of bound arguments.
Definition: callback.h:752
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:257
std::string Append(std::string left, std::string right)
Join two file system path elements.
Definition: system-path.cc:239
Debug message logging.
std::string Encode(const std::string &source)
HTML-encode a string, for PrintDoxygenUsage().
Definition: command-line.cc:60
bool UserItemParse< bool >(const std::string &value, bool &dest)
Specialization of CommandLine::UserItem::Parse() to bool.
bool UserItemParse< uint8_t >(const std::string &value, uint8_t &dest)
Specialization of CommandLine::UserItem::Parse() to uint8_t to distinguish from char.
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:850
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:129
value
Definition: second.py:41
cmd
Definition: second.py:33
ns3::StringValue attribute value declarations.
Attribute implementation.
Definition: type-id.h:82
Ptr< const AttributeChecker > checker
Checker object.
Definition: type-id.h:96
Ptr< const AttributeValue > initialValue
Configured initial value.
Definition: type-id.h:92
std::string help
Attribute help string.
Definition: type-id.h:86
ns3::SystemPath declarations.
ns3::TypeId declaration; inline and template implementations.
class ns3::Version definition