|
25 | 25 |
|
26 | 26 | #include <algorithm> |
27 | 27 | #include <array> |
| 28 | +#include <charconv> |
28 | 29 | #include <cstdio> |
29 | 30 | #include <cstdlib> |
30 | 31 | #include <fstream> |
@@ -152,6 +153,7 @@ driver::driver() |
152 | 153 | dry_run(false), |
153 | 154 | input_file(), |
154 | 155 | output_file(""), |
| 156 | + device_idx(0), |
155 | 157 | device_name_substring(""), |
156 | 158 | cl_build_args(), |
157 | 159 | strip_binary_header(false), |
@@ -185,6 +187,9 @@ optional arguments: |
185 | 187 | output file path, defaults to the name of the last |
186 | 188 | input file "<input>.bin" if present, or "-" otherwise |
187 | 189 | to write to standard output |
| 190 | + --device-idx index |
| 191 | + the index (1..N) of the device to select. Takes precedence |
| 192 | + over --device |
188 | 193 | -d name, --device name |
189 | 194 | a substring of the device name to select, choose from:%s |
190 | 195 | --list-devices print the list of available devices and exit |
@@ -275,6 +280,18 @@ result driver::parseArguments(int argc, char **argv) { |
275 | 280 | CHECK(parser.add_argument({"-o", output_file})); |
276 | 281 | CHECK(parser.add_argument({"--output", output_file})); |
277 | 282 |
|
| 283 | + CHECK(parser.add_argument({ |
| 284 | + "--device-idx", |
| 285 | + [](auto&&...){ return parse::INCOMPLETE; }, |
| 286 | + [this](cargo::string_view str_value){ |
| 287 | + auto [ptr, ec] = std::from_chars(str_value.begin(), str_value.end(), device_idx); |
| 288 | + if ((ptr != str_value.end()) || (device_idx == 0)) { |
| 289 | + return parse::INVALID; |
| 290 | + } |
| 291 | + return parse::COMPLETE; |
| 292 | + }, |
| 293 | + })); |
| 294 | + |
278 | 295 | CHECK(parser.add_argument({"-d", device_name_substring})); |
279 | 296 | CHECK(parser.add_argument({"--device", device_name_substring})); |
280 | 297 |
|
@@ -743,38 +760,51 @@ result driver::findDevice() { |
743 | 760 | return result::failure; |
744 | 761 | } |
745 | 762 |
|
746 | | - if (compilers.size() > 1 && device_name_substring.empty()) { |
747 | | - (void)std::fprintf(stderr, |
748 | | - "error: Multiple devices available, please choose one " |
749 | | - "(--device NAME):\n"); |
750 | | - printMuxCompilers(compilers); |
751 | | - return result::failure; |
752 | | - } |
753 | | - |
754 | | - bool found = false; |
755 | | - for (auto compiler : compilers) { |
756 | | - bool matches = true; |
757 | | - if (!device_name_substring.empty()) { |
758 | | - matches &= matchSubstring(compiler->device_info->device_name, |
759 | | - device_name_substring); |
760 | | - } |
761 | | - if (matches) { |
762 | | - if (found) { |
763 | | - (void)std::fprintf( |
764 | | - stderr, "error: Device selection ambiguous, available devices:\n"); |
| 763 | + if (device_idx != 0) { |
| 764 | + if (device_idx > compilers.size()) { |
| 765 | + (void)std::fprintf(stderr, |
| 766 | + "error: Invalid device selection; out of bounds. " |
| 767 | + "Available devices:\n"); |
765 | 768 | printMuxCompilers(compilers); |
766 | 769 | return result::failure; |
| 770 | + } |
| 771 | + |
| 772 | + compiler_info = compilers[device_idx - 1]; |
| 773 | + |
| 774 | + } else { |
| 775 | + if (compilers.size() > 1 && device_name_substring.empty()) { |
| 776 | + (void)std::fprintf(stderr, |
| 777 | + "error: Multiple devices available, please choose one " |
| 778 | + "(--device NAME | --device-idx INDEX):\n"); |
| 779 | + printMuxCompilers(compilers); |
| 780 | + return result::failure; |
| 781 | + } |
| 782 | + |
| 783 | + bool found = false; |
| 784 | + for (auto compiler : compilers) { |
| 785 | + bool matches = true; |
| 786 | + if (!device_name_substring.empty()) { |
| 787 | + matches &= matchSubstring(compiler->device_info->device_name, |
| 788 | + device_name_substring); |
| 789 | + } |
| 790 | + if (matches) { |
| 791 | + if (found) { |
| 792 | + (void)std::fprintf( |
| 793 | + stderr, "error: Device selection ambiguous, available devices:\n"); |
| 794 | + printMuxCompilers(compilers); |
| 795 | + return result::failure; |
| 796 | + } |
| 797 | + found = true; |
| 798 | + compiler_info = compiler; |
767 | 799 | } |
768 | | - found = true; |
769 | | - compiler_info = compiler; |
770 | 800 | } |
771 | | - } |
772 | | - if (!found) { |
773 | | - (void)std::fprintf( |
774 | | - stderr, |
775 | | - "error: No device matched the given substring, available devices:\n"); |
776 | | - printMuxCompilers(compilers); |
777 | | - return result::failure; |
| 801 | + if (!found) { |
| 802 | + (void)std::fprintf( |
| 803 | + stderr, |
| 804 | + "error: No device matched the given substring, available devices:\n"); |
| 805 | + printMuxCompilers(compilers); |
| 806 | + return result::failure; |
| 807 | + } |
778 | 808 | } |
779 | 809 |
|
780 | 810 | if (verbose) { |
|
0 commit comments