summaryrefslogtreecommitdiffstats
path: root/task1/getoptwrapper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'task1/getoptwrapper.cpp')
-rw-r--r--task1/getoptwrapper.cpp191
1 files changed, 191 insertions, 0 deletions
diff --git a/task1/getoptwrapper.cpp b/task1/getoptwrapper.cpp
new file mode 100644
index 0000000..1efd603
--- /dev/null
+++ b/task1/getoptwrapper.cpp
@@ -0,0 +1,191 @@
1/**
2 * $Id: getoptwrapper.cpp 2 2009-10-31 02:48:23Z l0728348 $
3 *
4 * Copyright 2009
5 *
6 * @author Manuel Mausz (0728348)
7 * @brief Wraps around getopt_long() using two classes
8 * class CommandOption represents a valid commandline option
9 * class CommandOptionParse calls getopt_long
10 * and generates usage message
11 */
12
13#include <sstream>
14#include <iomanip>
15#include <algorithm>
16#include <stdexcept>
17#include <unistd.h>
18#include "getoptwrapper.h"
19
20using namespace std;
21
22CommandOptionParse::CommandOptionList cmdoptionlist;
23
24/*----------------------------------------------------------------------------*/
25
26const std::string CommandOption::printParameters()
27{
28 ostringstream oss;
29
30 if (!m_longopt.empty() && m_shortopt != 0)
31 oss << "-" << m_shortopt << " [ --" << m_longopt << " ]";
32 else if (!m_longopt.empty() && m_shortopt == 0)
33 oss << "--" << m_longopt;
34 else if (m_longopt.empty() && m_shortopt != 0)
35 oss << "-" << m_shortopt;
36
37 if (m_type == needArg)
38 oss << " arg";
39 else if (m_type == optArg)
40 oss << " [ arg ]";
41
42 return oss.str();
43}
44
45/*----------------------------------------------------------------------------*/
46
47void CommandOption::foundOption(const char *value)
48{
49 m_count++;
50 if (value != NULL)
51 m_value = value;
52}
53
54/*----------------------------------------------------------------------------*/
55
56bool CommandOptionParse::parse()
57{
58 CommandOptionList::iterator it;
59
60 /* build optstring */
61 m_optstring = "";
62 for (it = m_cmdlist.begin(); it != m_cmdlist.end(); ++it)
63 {
64 CommandOption *opt = *it;
65 if (opt->m_shortopt == 0)
66 continue;
67
68 m_optstring += opt->m_shortopt;
69 if (opt->m_type == CommandOption::needArg)
70 m_optstring += ':';
71 if (opt->m_type == CommandOption::optArg)
72 m_optstring += "::";
73 }
74
75 /* build longopts */
76 if (m_longopts != NULL)
77 delete[] m_longopts;
78 m_longopts = new option[m_cmdlist.size() + 1];
79 int i = 0;
80 for (it = m_cmdlist.begin(); it != m_cmdlist.end(); ++it)
81 {
82 CommandOption *opt = *it;
83 if (opt->m_longopt.empty())
84 continue;
85
86 m_longopts[i].name = opt->m_longopt.c_str();
87 m_longopts[i].has_arg = opt->m_type;
88 m_longopts[i].flag = 0;
89 m_longopts[i].val = 0;
90 ++i;
91 }
92
93 /* append NULL-row */
94 m_longopts[i].name = 0;
95 m_longopts[i].has_arg = 0;
96 m_longopts[i].flag = 0;
97 m_longopts[i].val = 0;
98
99 //opterr = 0; // no errors from getopt_long!
100 int opt;
101 int optindex = 0;
102 while ((opt = getopt_long(m_argc, m_argv, m_optstring.c_str(), m_longopts, &optindex)) != -1)
103 {
104 if (opt == '?')
105 return 0;
106
107 for (it = m_cmdlist.begin(); it != m_cmdlist.end(); ++it)
108 {
109 CommandOption *option = *it;
110 if (opt == 0)
111 {
112 if (option->m_longopt == m_longopts[optindex].name)
113 option->foundOption(optarg);
114 }
115 else if (opt == option->m_shortopt)
116 option->foundOption(optarg);
117 }
118 }
119
120 return 1;
121}
122
123/*----------------------------------------------------------------------------*/
124
125const std::string CommandOptionParse::usage()
126{
127 ostringstream oss;
128 string me(m_argv[0]);
129
130 /* build usage/synopsis */
131 oss << "Usage: ";
132 if (!m_synopsis.empty())
133 {
134 oss << me << " " << m_synopsis.at(0) << endl;
135 for (unsigned i = 1; i < m_synopsis.size(); ++i)
136 oss << " " << me << " " << m_synopsis.at(i) << endl;
137 }
138 else
139 oss << me << " [OPTION]..." << endl;
140
141 /* find maximum width of options */
142 CommandOptionList::iterator it;
143 unsigned width = 20; // default
144 for (it = m_cmdlist.begin(); it != m_cmdlist.end(); ++it)
145 {
146 stringstream tmpss;
147 tmpss << (*it)->printParameters();
148 width = (max)(width, static_cast<unsigned>(tmpss.str().size()));
149 }
150 width += 2;
151
152 /* print allowed options + description */
153 oss << endl << m_description << ":" << endl;
154 for (it = m_cmdlist.begin(); it != m_cmdlist.end(); ++it)
155 {
156 oss << " " << setw(width) << left << (*it)->printParameters()
157 << (*it)->m_description << endl;
158 }
159
160 return oss.str();
161}
162
163/*----------------------------------------------------------------------------*/
164
165CommandOption& CommandOptionParse::operator[](const std::string& longopt)
166{
167 CommandOptionList::iterator it;
168 for (it = m_cmdlist.begin(); it != m_cmdlist.end(); ++it)
169 {
170 CommandOption *opt = *it;
171 if (opt->m_longopt == longopt)
172 return *opt;
173 }
174 throw out_of_range("option not found");
175}
176
177/*----------------------------------------------------------------------------*/
178
179CommandOption& CommandOptionParse::operator[](const char shortopt)
180{
181 CommandOptionList::iterator it;
182 for (it = m_cmdlist.begin(); it != m_cmdlist.end(); ++it)
183 {
184 CommandOption *opt = *it;
185 if (opt->m_shortopt == shortopt)
186 return *opt;
187 }
188 throw out_of_range("option not found");
189}
190
191/* vim: set et sw=2 ts=2: */