-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcmd_parser.cpp
More file actions
90 lines (78 loc) · 2.75 KB
/
Copy pathcmd_parser.cpp
File metadata and controls
90 lines (78 loc) · 2.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include "cmd_parser.hpp"
#include <charconv>
#include <filesystem>
#include <optional>
#include <string>
#include <string_view>
#include <system_error>
namespace {
// Tries to convert a string_view to an integer.
// Returns std::nullopt if the conversion fails.
std::optional<int> string_to_int(std::string_view s, int base = 10) {
int value{};
const auto* const last = s.data() + s.size();
auto [ptr, ec] = std::from_chars(s.data(), last, value, base);
if (ec == std::errc() && ptr == last) {
return value;
}
return std::nullopt;
}
} // namespace
CommandLineArgs parse_command_line(int argc, char** argv) {
CommandLineArgs args;
if (argc <= 1) {
args.is_valid = false;
args.error_message = "No arguments provided.";
return args;
}
for (int i = 1; i < argc; ++i) {
const std::string_view current_arg = argv[i];
if (current_arg == "-i") {
if (i + 1 >= argc) {
args.is_valid = false;
args.error_message = "Missing filename after -i.";
return args;
}
const std::string_view input_file = argv[i + 1];
if (!std::filesystem::exists(input_file)) {
args.is_valid = false;
args.error_message = "Unable to locate input file: " + std::string(input_file);
return args;
}
args.input_config = InputConfig{std::string(input_file)};
i += 1; // Consume the filename argument
} else if (current_arg == "-o") {
if (i + 3 >= argc) {
args.is_valid = false;
args.error_message =
"-o option requires exactly 3 arguments: <file> <addr> <size>.";
return args;
}
const std::string_view output_file = argv[i + 1];
const auto addr = string_to_int(argv[i + 2]);
const auto size = string_to_int(argv[i + 3]);
if (!addr || !size) {
args.is_valid = false;
args.error_message = "Invalid address or size for -o option.";
return args;
}
args.output_config = OutputConfig{
.file_name = std::string(output_file),
.begin_address = *addr,
.size = *size,
};
i += 3; // Consume the 3 arguments for -o
} else {
args.is_valid = false;
args.error_message = "Unknown argument: " + std::string(current_arg);
return args;
}
}
if (!args.input_config) {
args.is_valid = false;
args.error_message = "Input file must be specified with -i.";
return args;
}
args.is_valid = true;
return args;
}