13 #include "boost/program_options.hpp"
33 namespace po = boost::program_options;
38 po::options_description inputopt(
"Input/output");
39 inputopt.add_options()
40 (
"input", po::value<std::vector<std::string>>(),
"input file")
43 po::options_description genopt(
"General");
45 (
"help,?",
"print usage instructions and exit")
46 (
"version,V",
"print usage instructions")
49 po::options_description allopt(
"Options");
50 allopt.add(inputopt).add(genopt);
52 po::positional_options_description pos;
58 po::variables_map optmap;
60 po::command_line_parser(argc, argv)
61 .
options(allopt).positional(pos).run(),
69 std::optional<int> exitWithCode;
70 if (optmap.count(
"verbose")) {
75 if (optmap.count(
"help")) {
77 <<
"Parses the trigger packet strings from the input file(s) and prints its interpretation."
78 <<
"\nIf no file is specified in the command line (option or positional argument),"
79 <<
"\nstrings are read from the standard input stream."
86 if (exitWithCode)
std::exit(*exitWithCode);
102 {
"Cryo. (EAST|WEST) Connector . and .", 1U }
103 , {
"Trigger Type", 1U }
108 parsedData =
parser(triggerString);
112 std::cerr <<
"Error parsing trigger data:\n" << std::string(80,
'-')
113 <<
"\n" << triggerString <<
"\n" << std::string(80,
'-')
114 <<
"Error: " << e.what() << std::endl;
128 std::map<std::string, std::vector<std::string>> typeKeys = {
131 "Cryo1 EAST Connector 0 and 1"
132 ,
"Cryo1 EAST Connector 2 and 3"
133 ,
"Cryo2 WEST Connector 0 and 1"
134 ,
"Cryo2 WEST Connector 2 and 3"
140 std::map<std::string, std::string> keyType;
141 for (
auto const& [
type, keys ]: typeKeys)
142 for (std::string
const& key: keys) keyType[key] =
type;
145 <<
"Trigger data (" << triggerString.length() <<
" char):"
146 <<
"\n" << triggerString
150 std::cout <<
"\n '" << item.key() <<
"':";
152 std::string
type = keyType.count(item.key())? keyType[item.key()]:
"auto";
153 if (type.empty()) type =
"auto";
155 if (type ==
"hex64") {
157 std::vector<std::uint64_t>
const&
values = item.getVector<std::uint64_t>
159 if (values.empty())
std::cout <<
" <no number>";
160 else if (values.size() == 1)
std::cout <<
" " << std::hex << values[0];
162 auto iValue = values.begin(), vend = values.end();
163 std::cout <<
" (" << values.size() <<
" numbers) "
164 << std::hex << *iValue;
165 while (++iValue != vend)
std::cout <<
" , " << *iValue;
167 std::cout << std::dec <<
" (" << type <<
")";
175 std::vector<int>
values = item.getVector<
int>();
176 if (values.empty())
std::cout <<
" <no number>";
177 else if (values.size() == 1)
std::cout <<
" " << values[0];
179 auto iValue = values.begin(), vend = values.end();
180 std::cout <<
" (" << values.size() <<
" numbers) " << *iValue;
181 while (++iValue != vend)
std::cout <<
" , " << *iValue;
191 else if (type !=
"auto") type =
"?";
196 std::vector<std::string>
const&
values = item.values();
197 if (values.empty())
std::cout <<
" <no value>";
198 else if (values.size() == 1)
std::cout <<
" " << values[0];
200 auto iValue = values.begin(), vend = values.end();
201 std::cout <<
" (" << values.size() <<
" values) " << *iValue;
202 while (++iValue != vend)
std::cout <<
" , " << *iValue;
216 int main(
int argc,
char** argv) {
218 boost::program_options::variables_map
const options
221 std::vector<std::string> inputFilePaths;
222 if (options.count(
"input"))
223 inputFilePaths = options[
"input"].as<std::vector<std::string>>();
224 if (inputFilePaths.empty()) inputFilePaths.push_back(
"");
227 unsigned int lineCount = 0U;
228 for (std::string
const& inputFilePath: inputFilePaths) {
231 std::optional<std::ifstream> realInputFile;
232 if (inputFilePath.empty())
233 std::clog <<
"Reading data from standard input." << std::endl;
235 realInputFile.emplace(inputFilePath);
236 if (!realInputFile->good()) {
237 std::cerr <<
"FATAL: can't open input file '" << inputFilePath <<
"'."
241 std::clog <<
"Reading data from '" << inputFilePath <<
"'." << std::endl;
243 std::istream& inputFile = realInputFile? *realInputFile: std::cin;
245 unsigned int fileLineCount = 0U;
247 while (std::getline(inputFile, line)) {
254 lineCount += fileLineCount;
260 std::cerr <<
"Parsing failed for " << nErrors <<
"/" << lineCount
261 <<
" lines." << std::endl;
264 return (nErrors == 0)? 0: 1;
Parser to fill a KeyValuesData structure out of a character buffer.
decltype(auto) items() const noexcept
Returns a forward-iterable list of references to items.
BEGIN_PROLOG could also be cerr
process_name opflash opflashana store
static std::string const ProgramVersion
Simple parser for comma-separated text.
int processTriggerData(std::string const &triggerString)
Representation of a single item of data: a key and several values.
Collection of items with key/values structure.
KeyedCSVparser & addPatterns(std::initializer_list< std::pair< std::regex, unsigned int >> patterns)
Adds known patterns.
then echo echo For and will not be changed by echo further linking echo echo B echo The symbol is in the uninitialized data multiple common symbols may appear with the echo same name If the symbol is defined the common echo symbols are treated as undefined references For more echo details on common see the discussion of warn common echo in *Note Linker options
boost::program_options::variables_map parseCommandLine(int argc, char **argv)
int main(int argc, char **argv)
BEGIN_PROLOG could also be cout