Skip to content

Commit b9e6fcb

Browse files
author
Avi SZYCHTER
committed
Improved CLI parsing, now can possibly execute all planned operations
1 parent 661020b commit b9e6fcb

File tree

1 file changed

+49
-20
lines changed

1 file changed

+49
-20
lines changed

utils/can-parse/can-parse.cpp

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
#include <iostream>
44
#include <cstring>
55
#include <algorithm>
6-
6+
#include <set>
77
#include "operations.h"
8-
8+
#include <iomanip>
99

1010
using namespace CppCAN::can_parse;
1111

@@ -22,63 +22,91 @@ static std::string CHECKFRAME_ACTION = "checkframe";
2222
static std::string PRINTFRAME_ACTION = "printframe";
2323

2424
void showUsage(std::ostream& ostrm, char* program_name) {
25-
ostrm << "Usage: " << program_name << " [ACTION] <path/to/file>" << std::endl;
25+
ostrm << "Usage: " << program_name << " [ACTION [ARGUMENTS]] <path/to/file>" << std::endl;
2626
ostrm << "When no action is specified, defaults to " << PRINTFRAME_ACTION << std::endl;
2727
ostrm << "Possible actions: " << std::endl;
28-
ostrm << "\t" << PRINTFRAME_ACTION << "\tPrint the content of the CAN database" << std::endl;
29-
ostrm << "\t" << CHECKFRAME_ACTION << "\tCheck different properties of the CAN database" << std::endl;
28+
ostrm << "\t" << std::left << std::setw(22) << (PRINTFRAME_ACTION + " [CAN ID]") << "Print the content of the CAN database" << std::endl;
29+
ostrm << "\t" << std::setw(22) << "" << "if CAN ID is specified, prints the details of the given frame" << std::endl;
30+
ostrm << "\t" << std::setw(22) << (CHECKFRAME_ACTION + " [CAN ID]") << "Check different properties of the CAN database" << std::endl;
31+
ostrm << "\t" << std::setw(22) << "" << "if CAN ID is specified, print the check details of the given frame" << std::endl;
3032
ostrm << "Currently supported formats: DBC" << std::endl;
3133
}
3234

3335

34-
std::tuple<CanParseAction, std::string> extractAction(int argc, char** argv) {
36+
std::tuple<CanParseAction, std::string, uint32_t> extractAction(int argc, char** argv) {
3537
std::vector<std::string> args(argv + 1, argv + argc); // +1 so we ignore the executable name
3638

3739
CanParseAction action = None;
3840
std::string src_file;
41+
uint32_t detail_frame = 0;
3942

4043
if (args.size() < 1) {
4144
throw CppCAN::can_parse::CanParseException("Not enough arguments");
4245
}
4346

44-
size_t i = 0;
47+
std::set<std::string> options;
48+
49+
bool check_action = true;
50+
bool check_args = false;
4551
for(const std::string& arg : args) {
4652
// First argument, we check for potential actions
47-
if(i++ == 0) {
53+
if(arg.size() > 0 && arg[0] == '-') {
54+
options.insert(arg);
55+
continue;
56+
}
57+
else if(check_action) {
4858
if(arg == CHECKFRAME_ACTION) {
4959
action = CheckAll;
60+
check_args = true;
61+
check_action = false;
5062
continue;
5163
}
5264
else if(arg == PRINTFRAME_ACTION) {
5365
action = PrintAll;
66+
check_args = true;
67+
check_action = false;
5468
continue;
5569
}
56-
}
57-
58-
// Check for options
59-
if(arg.size() > 0 && arg[0] == '-') {
60-
if(arg == "-h" || arg == "--help") {
61-
action = Help;
70+
else {
71+
action = PrintAll;
72+
check_action = false;
6273
}
6374
}
64-
// This is a file path (for now)
65-
else {
66-
src_file = arg;
75+
else if(check_args) {
76+
check_args = false;
77+
78+
try {
79+
detail_frame = std::stoul(arg);
80+
action = static_cast<CanParseAction>(static_cast<int>(action) + 1);
81+
continue;
82+
} catch(const std::logic_error& e) {
83+
// The argument is not related ....
84+
// Probably a file name, we stick to PrintAll/CheckAll
85+
}
6786
}
87+
88+
// At this point, nothing has matched. The only valid thing that this could be
89+
// is the file name of the database to parse.
90+
src_file = arg;
91+
}
92+
93+
if(options.count("-h") > 0 || options.count("--help")) {
94+
action = Help;
6895
}
6996

7097
if(action != Help && src_file.size() == 0)
7198
throw CppCAN::can_parse::CanParseException("No source file specified");
7299

73-
return std::make_tuple(action != None ? action : PrintAll, src_file);
100+
return std::make_tuple(action != None ? action : PrintAll, src_file, detail_frame);
74101
}
75102

76103
int main(int argc, char** argv) {
77104
std::string src_file;
78105
CanParseAction action;
106+
uint32_t detail_frame;
79107

80108
try {
81-
std::tie(action, src_file) = extractAction(argc, argv);
109+
std::tie(action, src_file, detail_frame) = extractAction(argc, argv);
82110
}
83111
catch(const CanParseException& e) {
84112
std::cerr << "Invalid use of the program: " << e.what() << std::endl;
@@ -102,6 +130,7 @@ int main(int argc, char** argv) {
102130
return 2;
103131
}
104132

133+
std::cout << (detail_frame == 0 ? "Print all" : "Print CAN ID " + std::to_string(detail_frame)) << std::endl;
105134
switch(action) {
106135
case PrintAll:
107136
print_all_frames(db);
@@ -116,7 +145,7 @@ int main(int argc, char** argv) {
116145
break;
117146

118147
default:
119-
std::cerr << "Acton not implemented yet." << std::endl;
148+
std::cerr << "Action not implemented yet." << std::endl;
120149
return 3;
121150
}
122151
return 0;

0 commit comments

Comments
 (0)