tudocomp
– The TU Dortmund Compression Framework
Options.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <iostream>
4 #include <getopt.h>
5 
7 namespace tdc_driver {
8 
9 // getopt data
10 constexpr int OPT_HELP = 1000;
11 constexpr int OPT_RAW = 1001;
12 constexpr int OPT_STDIN = 1002;
13 constexpr int OPT_STDOUT = 1003;
14 
15 constexpr option OPTIONS[] = {
16  {"algorithm", required_argument, nullptr, 'a'},
17  {"decompress", no_argument, nullptr, 'd'},
18  {"force", no_argument, nullptr, 'f'},
19  {"generator", required_argument, nullptr, 'g'},
20  {"help", no_argument, nullptr, OPT_HELP},
21  {"list", no_argument, nullptr, 'l'},
22  {"output", required_argument, nullptr, 'o'},
23  {"stats", optional_argument, nullptr, 's'},
24  {"version", no_argument, nullptr, 'v'},
25  {"raw", no_argument, nullptr, OPT_RAW},
26  {"usestdin", no_argument, nullptr, OPT_STDIN},
27  {"usestdout", no_argument, nullptr, OPT_STDOUT},
28  {"logdir", required_argument, nullptr, 'L'},
29  {"loglevel", required_argument, nullptr, 'O'},
30  {"logverbosity", required_argument, nullptr, 'V'},
31  {0, 0, 0, 0} // termination (required last entry!!)
32 };
33 
34 class Options {
35 public:
36  static inline void print_usage(const std::string& cmd, std::ostream& out) {
37  using namespace std;
38 
39  // Usage
40  out << left;
41  out << setw(7) << "Usage: " << cmd << " [OPTION] "
42  << setw(11) << "FILE" << "(1)" << endl;
43  out << setw(7) << "or: " << cmd << " [OPTION] "
44  << setw(11) << "--usestdin" << "(2)" << endl;
45  out << setw(7) << "or: " << cmd << " [OPTION] "
46  << setw(11) << "-g GENERATOR" << "(3)" << endl;
47 
48  // Brief description
49  out << endl;
50  out << "Compresses or decompresses a file (1), an input received via stdin (2) or a" << endl;
51  out << "generated string (3). Depending on the selected input, an output (either a" << endl;
52  out << "file or stdout) may need to be specified." << endl;
53 
54  // Options
55  out << endl;
56  out << "Options:" << endl;
57 
58  constexpr int W_SF = 4;
59  constexpr int W_NOSF = 6;
60  constexpr int W_LF = 24;
61  constexpr int W_INDENT = 30;
62 
63  // -a, --algorithm
64  out << right << setw(W_SF) << "-a" << ", "
65  << left << setw(W_LF) << "--algorithm=ALGORITHM"
66  << "use ALGORITHM for (de-)compression"
67  << endl << setw(W_INDENT) << "" << "(use -l for more information)"
68  << endl;
69 
70  // -d, --decompress
71  out << right << setw(W_SF) << "-d" << ", "
72  << left << setw(W_LF) << "--decompress"
73  << "decompress the input (instead of compressing it)"
74  << endl;
75 
76  // -f, --force
77  out << right << setw(W_SF) << "-f" << ", "
78  << left << setw(W_LF) << "--force"
79  << "overwrite output file if it exists"
80  << endl;
81 
82  // -g, --generator
83  out << right << setw(W_SF) << "-g" << ", "
84  << left << setw(W_LF) << "--generator=GENERATOR"
85  << "generate the input using GENERATOR"
86  << endl << setw(W_INDENT) << "" << "(use -l for more information)"
87  << endl;
88 
89  // -l, --list
90  out << right << setw(W_SF) << "-l" << ", "
91  << left << setw(W_LF) << "--list"
92  << "list available (de-)compression algorithms"
93  << endl;
94 
95  // -o, --output=FILE
96  out << right << setw(W_SF) << "-o" << ", "
97  << left << setw(W_LF) << "--output=FILE"
98  << "write output to FILE."
99  << endl;
100 
101  // -s, --stats
102  out << right << setw(W_SF) << "-s" << ", "
103  << left << setw(W_LF) << "--stats[=TITLE]"
104  << "print (de-)compression statistics in JSON format"
105  << endl;
106 
107  // --help
108  out << right << setw(W_NOSF) << ""
109  << left << setw(W_LF) << "--help"
110  << "display this help"
111  << endl;
112 
113  // --raw
114  out << right << setw(W_NOSF) << ""
115  << left << setw(W_LF) << "--raw"
116  << "(de-)compress without writing/reading a header"
117  << endl;
118 
119  // --usestdin
120  out << right << setw(W_NOSF) << ""
121  << left << setw(W_LF) << "--usestdin"
122  << "use stdin for input"
123  << endl;
124 
125  // --usestdout
126  out << right << setw(W_NOSF) << ""
127  << left << setw(W_LF) << "--usestdout"
128  << "use stdout for input"
129  << endl;
130 
131  // -v, --version
132  out << right << setw(W_SF) << "-v" << ", "
133  << left << setw(W_LF) << "--version"
134  << "print the version number of this build"
135  << endl;
136 
137  // -L, --logdir
138  out << right << setw(W_SF) << "-L" << ", "
139  << left << setw(W_LF) << "--logdir=path"
140  << "instead of logging to stdout use a log dir"
141  << endl << setw(W_INDENT) << "" << "in which log files are saved"
142  << endl;
143 
144  // -O, --lOglevel
145  out << right << setw(W_SF) << "-O" << ", "
146  << left << setw(W_LF) << "--loglevel=[0|1|2|3]"
147  << "log messages at or above this level"
148  << endl << setw(W_INDENT) << "" << "levels are INFO, WARNING, ERROR, and FATAL, "
149  << endl << setw(W_INDENT) << "" << "enumerated by 0, 1, 2, and 3, respectively."
150  << endl;
151 
152  // -V, --logverbosity
153  out << right << setw(W_SF) << "-V" << ", "
154  << left << setw(W_LF) << "--logverbosity=[0|1|2]"
155  << "show all VLOG(m) messages for m less or equal the value of this flag"
156  << endl;
157  }
158 
159 private:
160  // fields
161  bool m_unknown_options;
162 
163  bool m_help;
164  bool m_version;
165  bool m_list;
166 
167  std::string m_algorithm;
168 
169  std::string m_output;
170  bool m_force;
171  bool m_stdin, m_stdout;
172  std::string m_generator;
173 
174  bool m_raw;
175  bool m_decompress;
176 
177  bool m_stats;
178  std::string m_stats_title;
179 
180  std::vector<std::string> m_remaining;
181 
182 public:
183  // The reference-based accessors will
184  // get invalidated in case of a move or copy, so forbid them
185  Options(const Options& other) = delete;
186  Options(Options&& other) = delete;
187 
188  inline Options(int argc, char **argv) :
189  m_unknown_options(false),
190  m_help(false),
191  m_version(false),
192  m_list(false),
193  m_force(false),
194  m_stdin(false),
195  m_stdout(false),
196  m_raw(false),
197  m_decompress(false),
198  m_stats(false)
199  {
200  int c, option_index = 0;
201  while((c = getopt_long(argc, argv, "O:V:L:a:dfg:lo:s::v",
202  OPTIONS, &option_index)) != -1) {
203 
204  switch(c) {
205  case 'a': // --algorithm=<optarg>
206  m_algorithm = std::string(optarg);
207  break;
208 
209  case 'd': // --decompress
210  m_decompress = true;
211  break;
212 
213  case 'f': // --force
214  m_force = true;
215  break;
216 
217  case 'g': // --generator=<optarg>
218  m_generator = std::string(optarg);
219  break;
220 
221  case 'l': // --list
222  m_list = true;
223  break;
224 
225 
226  case 'v': // --version
227  m_version = true;
228  break;
229 
230  case 'o': // --output=<optarg>
231  m_output = std::string(optarg);
232  break;
233 
234  case 's': // --stats=[optarg]
235  m_stats = true;
236  if(optarg) m_stats_title = std::string(optarg);
237  break;
238 
239  //logging
240  case 'L': // --logdir
241  FLAGS_log_dir = std::string(optarg);
242  FLAGS_logtostderr = 0;
243  break;
244  case 'V': // --logVerbosity
245  FLAGS_v = std::stoi(std::string(optarg));
246  break;
247  case 'O': // --lOglevel
248  FLAGS_minloglevel = std::stoi(std::string(optarg));
249  break;
250 
251  case OPT_HELP: // --help
252  m_help = true;
253  break;
254 
255  case OPT_RAW: // --raw
256  m_raw = true;
257  break;
258 
259  case OPT_STDIN: // --usestdin
260  m_stdin = true;
261  break;
262 
263  case OPT_STDOUT: // --usestdout
264  m_stdout = true;
265  break;
266 
267  case '?': // unknown option
268  m_unknown_options = true;
269  break;
270 
271  default: // declared, but unhandled
272  std::cerr << "Unhandled option \"" <<
273  OPTIONS[option_index].name << "\"";
274  break;
275  }
276  }
277 
278  // remaining options (e.g. filename)
279  while(optind < argc) {
280  m_remaining.emplace_back(argv[optind++]);
281  }
282  }
283 
284  // public accessors
285  const bool& unknown_options = m_unknown_options;
286 
287  const bool& help = m_help;
288  const bool& version = m_version;
289  const bool& list = m_list;
290 
291  const std::string& algorithm = m_algorithm;
292 
293  const std::string& output = m_output;
294  const bool& force = m_force;
295  const bool& stdin = m_stdin;
296  const bool& stdout = m_stdout;
297  const std::string& generator = m_generator;
298 
299  const bool& raw = m_raw;
300  const bool& decompress = m_decompress;
301 
302  const bool& stats = m_stats;
303  const std::string& stats_title = m_stats_title;
304 
305  const std::vector<std::string>& remaining = m_remaining;
306 };
307 
308 }
310