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