1 /**
2  * \file common.h
3  * Copyright 2007-2021 IMP Inventors. All rights reserved.
4  */
5 
6 #ifndef RMF_COMMON_H
7 #define RMF_COMMON_H
8 #include <RMF/config.h>
9 #include <boost/program_options.hpp>                      // IWYU pragma: export
10 #include <boost/program_options/options_description.hpp>  // IWYU pragma: export
11 #include <boost/program_options/parsers.hpp>              // IWYU pragma: export
12 #include <boost/program_options/positional_options.hpp>   // IWYU pragma: export
13 #include <boost/program_options/value_semantic.hpp>       // IWYU pragma: export
14 #include <boost/program_options/variables_map.hpp>        // IWYU pragma: export
15 #include <stdlib.h>
16 #include <iostream>
17 #include <string>
18 #include <vector>
19 #if RMF_HAS_DEPRECATED_BACKENDS
20 #include "RMF/HDF5/ConstFile.h"  // IWYU pragma: export
21 #endif
22 #include "RMF/log.h"      // IWYU pragma: export
23 #include "RMF/utility.h"  // IWYU pragma: export
24 
25 namespace {
26 extern std::string description;
27 
28 std::vector<std::string> positional_names;
29 boost::program_options::options_description options, positional_options;
30 boost::program_options::variables_map variables_map;
31 boost::program_options::positional_options_description
32     positional_options_description;
print_help_and_exit(char * argv[])33 void print_help_and_exit(char* argv[]) {
34   std::cerr << description << std::endl;
35   std::cerr << "Usage: " << argv[0] << " ";
36   for (unsigned int i = 0; i < positional_names.size(); ++i) {
37     std::cerr << positional_names[i] << " ";
38   }
39   std::cerr << std::endl;
40 
41   std::cerr << options << std::endl;
42   exit(1);
43 }
44 
print_version_and_exit()45 void print_version_and_exit() {
46   std::cout << "RMF version " << RMF_VERSION_MAJOR << "." << RMF_VERSION_MINOR
47             << std::endl;
48   exit(0);
49 }
50 
process_options(int argc,char * argv[])51 boost::program_options::variables_map process_options(int argc, char* argv[]) {
52   boost::program_options::options_description all;
53   std::string log_level("Off");
54   options.add_options()("help,h", "Show help on command line arguments.");
55   options.add_options()("version", "Show version information.");
56 #if RMF_HAS_DEPRECATED_BACKENDS
57   options.add_options()("hdf5-errors", "Show hdf5 errors.");
58 #endif
59 #if RMF_HAS_LOG4CXX
60   options.add_options()("log-level",
61                         boost::program_options::value<std::string>(&log_level),
62                         "What log level to use: Trace, Info, Warn, Error, Off");
63 #endif
64   all.add(positional_options).add(options);
65   boost::program_options::store(
66       boost::program_options::command_line_parser(argc, argv)
67           .options(all)
68           .positional(positional_options_description)
69           .run(),
70       variables_map);
71   boost::program_options::notify(variables_map);
72   if (variables_map.count("help")) {
73     print_help_and_exit(argv);
74   } else if (variables_map.count("version")) {
75     print_version_and_exit();
76   }
77 #if RMF_HAS_DEPRECATED_BACKENDS
78   if (variables_map.count("hdf5-errors")) {
79     RMF::HDF5::set_show_errors(true);
80   }
81 #endif
82   RMF::set_log_level(log_level);
83   return variables_map;
84 }
85 }
86 
87 #define RMF_ADD_INPUT_FILE(type)                                          \
88   std::string input;                                                      \
89   positional_names.push_back(type);                                       \
90   positional_options.add_options()(                                       \
91       "input-file,i", boost::program_options::value<std::string>(&input), \
92       "input " type " file");                                             \
93   positional_options_description.add("input-file", 1)
94 
95 #define RMF_ADD_OUTPUT_FILE(type)                                           \
96   std::string output;                                                       \
97   positional_names.push_back(type);                                         \
98   positional_options.add_options()(                                         \
99       "output-file,i", boost::program_options::value<std::string>(&output), \
100       "output " type " file");                                              \
101   positional_options_description.add("output-file", 1)
102 
103 #define RMF_ADD_FRAMES                                                    \
104   int start_frame = 0;                                                    \
105   options.add_options()("frame,f",                                        \
106                         boost::program_options::value<int>(&start_frame), \
107                         "First (or only) frame to use");                  \
108   int step_frame = std::numeric_limits<int>::max();                       \
109   options.add_options()("frame_step,s",                                   \
110                         boost::program_options::value<int>(&step_frame),  \
111                         "The step size for frames. Must be > 0.");
112 
113 #endif /* RMF_COMMON_H */
114