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