Browse Source

command line parser

develop
Robin Thoni 8 years ago
parent
commit
9cf74d5f25

+ 6
- 0
src/CMakeLists.txt View File

@@ -2,5 +2,11 @@ include_directories(.)
2 2
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
3 3
 set(SOURCE_FILES
4 4
   main.cpp
5
+  Interface/MainClass.cpp
6
+  Interface/MainClass.h
7
+  Interface/CommandLineParser.cpp
8
+  Interface/CommandLineParser.h
9
+  Interface/CommandLineOption.cpp
10
+  Interface/CommandLineOption.h
5 11
   )
6 12
 add_executable(pdns-slave ${SOURCE_FILES})

+ 98
- 0
src/Interface/CommandLineOption.cpp View File

@@ -0,0 +1,98 @@
1
+//
2
+// Created by robin on 8/8/15.
3
+//
4
+
5
+#include "CommandLineOption.h"
6
+
7
+CommandLineOption::CommandLineOption(const std::string &longName, char shortName, const std::string &description,
8
+                                     const std::string &valueName, const std::string &defaultValue)
9
+    : _longName(longName)
10
+    , _shortName(shortName)
11
+    , _description(description)
12
+    , _valueName(valueName)
13
+    , _defaultValue(defaultValue)
14
+    , _isSet(false)
15
+{
16
+}
17
+
18
+const std::string &CommandLineOption::getLongName() const
19
+{
20
+    return _longName;
21
+}
22
+
23
+void CommandLineOption::setLongName(const std::string &longName)
24
+{
25
+    _longName = longName;
26
+}
27
+
28
+char CommandLineOption::getShortName() const
29
+{
30
+    return _shortName;
31
+}
32
+
33
+void CommandLineOption::setShortName(char shortName)
34
+{
35
+    _shortName = shortName;
36
+}
37
+
38
+const std::string &CommandLineOption::getDescription() const
39
+{
40
+    return _description;
41
+}
42
+
43
+void CommandLineOption::setDescription(const std::string &description)
44
+{
45
+    _description = description;
46
+}
47
+
48
+const std::string &CommandLineOption::getValueName() const
49
+{
50
+    return _valueName;
51
+}
52
+
53
+void CommandLineOption::setValueName(const std::string &valueName)
54
+{
55
+    _valueName = valueName;
56
+}
57
+
58
+const std::string &CommandLineOption::getDefaultValue() const
59
+{
60
+    return _defaultValue;
61
+}
62
+
63
+void CommandLineOption::setDefaultValue(const std::string &defaultValue)
64
+{
65
+    _defaultValue = defaultValue;
66
+}
67
+
68
+const std::vector<std::string> &CommandLineOption::getValues() const
69
+{
70
+    return _values;
71
+}
72
+
73
+void CommandLineOption::addValue(const std::string &value)
74
+{
75
+    _values.push_back(value);
76
+}
77
+
78
+bool CommandLineOption::isSet() const
79
+{
80
+    return _isSet;
81
+}
82
+
83
+void CommandLineOption::setIsSet(bool isSet)
84
+{
85
+    _isSet = isSet;
86
+}
87
+
88
+bool CommandLineOption::hasValue() const
89
+{
90
+    return !_valueName.empty();
91
+}
92
+
93
+const std::string &CommandLineOption::getValue() const
94
+{
95
+    if (_values.empty())
96
+        return _defaultValue;
97
+    return _values[_values.size() - 1];
98
+}

+ 66
- 0
src/Interface/CommandLineOption.h View File

@@ -0,0 +1,66 @@
1
+//
2
+// Created by robin on 8/8/15.
3
+//
4
+
5
+#ifndef PDNS_SLAVE_COMMANDLINEOPTION_H
6
+#define PDNS_SLAVE_COMMANDLINEOPTION_H
7
+
8
+# include <string>
9
+# include <vector>
10
+
11
+class CommandLineOption
12
+{
13
+public:
14
+    CommandLineOption(const std::string& longName, char shortName, const std::string& description,
15
+                      const std::string& valueName = "", const std::string& defaultValue = "");
16
+
17
+    const std::string &getLongName() const;
18
+
19
+    void setLongName(const std::string &longName);
20
+
21
+    char getShortName() const;
22
+
23
+    void setShortName(char shortName);
24
+
25
+    const std::string &getDescription() const;
26
+
27
+    void setDescription(const std::string &description);
28
+
29
+    const std::string &getValueName() const;
30
+
31
+    void setValueName(const std::string &valueName);
32
+
33
+    const std::string &getDefaultValue() const;
34
+
35
+    void setDefaultValue(const std::string &defaultValue);
36
+
37
+    const std::vector<std::string> &getValues() const;
38
+
39
+    const std::string &getValue() const;
40
+
41
+    void addValue(const std::string &value);
42
+
43
+    bool isSet() const;
44
+
45
+    void setIsSet(bool isSet);
46
+
47
+    bool hasValue() const;
48
+
49
+private:
50
+    std::string _longName;
51
+
52
+    char _shortName;
53
+
54
+    std::string _description;
55
+
56
+    std::string _valueName;
57
+
58
+    std::string _defaultValue;
59
+
60
+    std::vector<std::string> _values;
61
+
62
+    bool _isSet;
63
+};
64
+
65
+
66
+#endif //PDNS_SLAVE_COMMANDLINEOPTION_H

+ 74
- 0
src/Interface/CommandLineParser.cpp View File

@@ -0,0 +1,74 @@
1
+//
2
+// Created by robin on 8/8/15.
3
+//
4
+
5
+#include <getopt.h>
6
+#include <iostream>
7
+#include "CommandLineParser.h"
8
+
9
+CommandLineParser::CommandLineParser(int argc, char **argv)
10
+    : _argc(argc)
11
+    , _argv(argv)
12
+{
13
+}
14
+
15
+bool CommandLineParser::parse()
16
+{
17
+    std::string shortOpts;
18
+    option opts[_options.size() + 1];
19
+    for (unsigned i = 0; i < _options.size(); ++i)
20
+    {
21
+        auto opt = _options[i];
22
+        shortOpts += opt->getShortName();
23
+        if (opt->hasValue())
24
+            shortOpts += ":";
25
+        opts[i].name = opt->getLongName().c_str();
26
+        opts[i].has_arg = opt->hasValue();
27
+        opts[i].flag = 0;
28
+        opts[i].val = opt->getShortName();
29
+    }
30
+    opts[_options.size()] = {0, 0, 0, 0};
31
+    int option;
32
+    extern int optind;
33
+    extern char* optarg;
34
+    bool valid = false;
35
+    while ((option = getopt_long(_argc, _argv, shortOpts.c_str(), opts, 0)) != -1)
36
+    {
37
+        for (unsigned i = 0; i < _options.size(); ++i)
38
+        {
39
+            bool optValid = false;
40
+            auto opt = _options[i];
41
+            if (opt->getShortName() == option)
42
+            {
43
+                optValid = true;
44
+                opt->setIsSet(true);
45
+                if (opt->hasValue())
46
+                    opt->addValue(optarg);
47
+            }
48
+            if (!optValid)
49
+                valid = false;
50
+        }
51
+    }
52
+    return optind == _argc && valid;
53
+}
54
+
55
+void CommandLineParser::addOption(CommandLineOption* opt)
56
+{
57
+    _options.push_back(opt);
58
+}
59
+
60
+int CommandLineParser::showHelp(int status, bool stdErr)
61
+{
62
+    auto& out = stdErr ? std::cerr : std::cout;
63
+    out << "Options:" << std::endl;
64
+    for (auto opt : _options)
65
+    {
66
+        out << "  -" << opt->getShortName() << ", --" << opt->getLongName();
67
+        if (opt->hasValue())
68
+        {
69
+            out << " <" << opt->getValueName() << "=" << opt->getDefaultValue() << ">";
70
+        }
71
+        out << " " << opt->getDescription() << std::endl;
72
+    }
73
+    return status;
74
+}

+ 30
- 0
src/Interface/CommandLineParser.h View File

@@ -0,0 +1,30 @@
1
+//
2
+// Created by robin on 8/8/15.
3
+//
4
+
5
+#ifndef PDNS_SLAVE_COMMANDLINEPARSER_H
6
+#define PDNS_SLAVE_COMMANDLINEPARSER_H
7
+
8
+# include "CommandLineOption.h"
9
+
10
+class CommandLineParser
11
+{
12
+public:
13
+    CommandLineParser(int argc, char** argv);
14
+
15
+    bool parse();
16
+
17
+    int showHelp(int status = 0, bool stdErr = true);
18
+
19
+    void addOption(CommandLineOption* opt);
20
+
21
+private:
22
+    int _argc;
23
+
24
+    char** _argv;
25
+
26
+    std::vector<CommandLineOption*> _options;
27
+};
28
+
29
+
30
+#endif //PDNS_SLAVE_COMMANDLINEPARSER_H

+ 36
- 0
src/Interface/MainClass.cpp View File

@@ -0,0 +1,36 @@
1
+//
2
+// Created by robin on 8/8/15.
3
+//
4
+
5
+#include <iostream>
6
+#include <sysexits.h>
7
+#include "CommandLineParser.h"
8
+#include "MainClass.h"
9
+
10
+MainClass::MainClass(int argc, char *argv[])
11
+    : _argc(argc)
12
+    , _argv(argv)
13
+{
14
+}
15
+
16
+int MainClass::main()
17
+{
18
+    CommandLineOption configFile("config", 'c', "Path to the configuration directory", "PATH", "/etc/pdns-slave/");
19
+    CommandLineOption help("help", 'h', "Displays this help", "", "");
20
+    CommandLineParser parser(_argc, _argv);
21
+    parser.addOption(&help);
22
+    parser.addOption(&configFile);
23
+    if (!parser.parse())
24
+        return parser.showHelp(EX_USAGE);
25
+    if (help.isSet())
26
+        return parser.showHelp(0, false);
27
+
28
+    auto path = configFile.getValue();
29
+    std::cout << "Using configuration directory " << path << std::endl;
30
+
31
+    auto sqlPath = path + "/sql.json";
32
+    auto hostsPath = path + "/hosts.json";
33
+    auto dhcpPath = path + "/dhcp.conf";
34
+
35
+    return 0;
36
+}

+ 23
- 0
src/Interface/MainClass.h View File

@@ -0,0 +1,23 @@
1
+//
2
+// Created by robin on 8/8/15.
3
+//
4
+
5
+#ifndef PDNS_SLAVE_MAINCLASS_H
6
+#define PDNS_SLAVE_MAINCLASS_H
7
+
8
+
9
+class MainClass {
10
+public:
11
+    MainClass(int argc, char* argv[]);
12
+
13
+    int main();
14
+
15
+private:
16
+    int _argc;
17
+
18
+    char** _argv;
19
+
20
+};
21
+
22
+
23
+#endif //PDNS_SLAVE_MAINCLASS_H

+ 4
- 1
src/main.cpp View File

@@ -1,4 +1,7 @@
1
+#include "Interface/MainClass.h"
2
+
1 3
 int main(int argc, char* argv[])
2 4
 {
3
-  return 0;
5
+    MainClass m(argc, argv);
6
+    return m.main();
4 7
 }

Loading…
Cancel
Save