From fc39f2e03852a779d353f62a93324d914826efad Mon Sep 17 00:00:00 2001 From: Roland Lutz Date: Mon, 10 Jul 2017 13:47:44 +0200 Subject: [PATCH 1/7] icemulti: Use standard macros for exit status --- icemulti/icemulti.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/icemulti/icemulti.cc b/icemulti/icemulti.cc index 637c3830472..c8cf5c27aed 100644 --- a/icemulti/icemulti.cc +++ b/icemulti/icemulti.cc @@ -24,7 +24,7 @@ #define log(...) fprintf(stderr, __VA_ARGS__); #define info(...) do { if (log_level > 0) fprintf(stderr, __VA_ARGS__); } while (0) -#define error(...) do { fprintf(stderr, "Error: " __VA_ARGS__); exit(1); } while (0) +#define error(...) do { fprintf(stderr, "Error: " __VA_ARGS__); exit(EXIT_FAILURE); } while (0) int log_level = 0; @@ -173,7 +173,7 @@ void usage() log(" -v\n"); log(" verbose (repeat to increase verbosity)\n"); log("\n"); - exit(1); + exit(EXIT_FAILURE); } int main(int argc, char **argv) @@ -278,5 +278,5 @@ int main(int argc, char **argv) } info("Done.\n"); - return 0; + return EXIT_SUCCESS; } From 21b2504aedf2faea144c81a00dbf19261a7ce85f Mon Sep 17 00:00:00 2001 From: Roland Lutz Date: Mon, 4 Sep 2017 15:44:02 +0200 Subject: [PATCH 2/7] icemulti: Report program name in error messages --- icemulti/icemulti.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/icemulti/icemulti.cc b/icemulti/icemulti.cc index c8cf5c27aed..32719d34d9d 100644 --- a/icemulti/icemulti.cc +++ b/icemulti/icemulti.cc @@ -21,10 +21,13 @@ #include #include +#include #define log(...) fprintf(stderr, __VA_ARGS__); #define info(...) do { if (log_level > 0) fprintf(stderr, __VA_ARGS__); } while (0) -#define error(...) do { fprintf(stderr, "Error: " __VA_ARGS__); exit(EXIT_FAILURE); } while (0) +#define error(...) do { fprintf(stderr, "%s: ", program_short_name); fprintf(stderr, __VA_ARGS__); exit(EXIT_FAILURE); } while (0) + +static char *program_short_name; int log_level = 0; @@ -187,6 +190,12 @@ int main(int argc, char **argv) std::unique_ptr images[NUM_IMAGES]; const char *outfile_name = NULL; + program_short_name = strrchr(argv[0], '/'); + if (program_short_name == NULL) + program_short_name = argv[0]; + else + program_short_name++; + for (int i = 1; i < argc; i++) { if (argv[i][0] == '-' && argv[i][1]) { From 450306dfb14a866f070f7370286880564316d1a9 Mon Sep 17 00:00:00 2001 From: Roland Lutz Date: Mon, 10 Jul 2017 14:03:17 +0200 Subject: [PATCH 3/7] icemulti: Give more information about I/O errors --- icemulti/icemulti.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/icemulti/icemulti.cc b/icemulti/icemulti.cc index 32719d34d9d..48e251257a9 100644 --- a/icemulti/icemulti.cc +++ b/icemulti/icemulti.cc @@ -58,7 +58,7 @@ static void write_bytes(std::ostream &ofs, uint32_t &file_offset, } static void write_file(std::ostream &ofs, uint32_t &file_offset, - std::istream &ifs) + std::istream &ifs, const char *filename) { const size_t bufsize = 8192; uint8_t *buffer = new uint8_t[bufsize]; @@ -66,7 +66,7 @@ static void write_file(std::ostream &ofs, uint32_t &file_offset, while(!ifs.eof()) { ifs.read(reinterpret_cast(buffer), bufsize); if (ifs.bad()) - error("Read error on input image"); + error("can't read input image `%s': %s\n", filename, strerror(errno)); write_bytes(ofs, file_offset, buffer, ifs.gcount()); } @@ -82,11 +82,12 @@ static void pad_to(std::ostream &ofs, uint32_t &file_offset, uint32_t target) } class Image { + const char *filename; std::ifstream ifs; uint32_t offs; public: - Image(const char *filename) : ifs(filename, std::ifstream::binary) {} + Image(const char *filename) : filename(filename), ifs(filename, std::ifstream::binary) {} size_t size(); void write(std::ostream &ofs, uint32_t &file_offset); @@ -104,7 +105,7 @@ size_t Image::size() void Image::write(std::ostream &ofs, uint32_t &file_offset) { - write_file(ofs, file_offset, ifs); + write_file(ofs, file_offset, ifs, filename); } class Header { @@ -268,7 +269,7 @@ int main(int argc, char **argv) if (outfile_name != NULL) { ofs.open(outfile_name, std::ofstream::binary); if (!ofs.is_open()) - error("Failed to open output file.\n"); + error("can't open output file `%s': %s\n", outfile_name, strerror(errno)); osp = &ofs; } else { osp = &std::cout; From e9e49bb5db7a29e6b479c7e7c4c0bb6b6e90078b Mon Sep 17 00:00:00 2001 From: Roland Lutz Date: Mon, 10 Jul 2017 14:03:56 +0200 Subject: [PATCH 4/7] icemulti: Add missing error checks --- icemulti/icemulti.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/icemulti/icemulti.cc b/icemulti/icemulti.cc index 48e251257a9..42b4dcb08db 100644 --- a/icemulti/icemulti.cc +++ b/icemulti/icemulti.cc @@ -87,19 +87,28 @@ class Image { uint32_t offs; public: - Image(const char *filename) : filename(filename), ifs(filename, std::ifstream::binary) {} - + Image(const char *filename); size_t size(); void write(std::ostream &ofs, uint32_t &file_offset); void place(uint32_t o) { offs = o; } uint32_t offset() const { return offs; } }; +Image::Image(const char *filename) : filename(filename), ifs(filename, std::ifstream::binary) +{ + if (ifs.fail()) + error("can't open input image `%s': %s\n", filename, strerror(errno)); +} + size_t Image::size() { ifs.seekg (0, ifs.end); + if (ifs.fail()) + error("can't seek on input image `%s': %s\n", filename, strerror(errno)); size_t length = ifs.tellg(); ifs.seekg (0, ifs.beg); + if (ifs.fail()) + error("can't seek on input image `%s': %s\n", filename, strerror(errno)); return length; } From ca90cc78e1a85ae902e2bc8cc2c6f8b4f7dd7b96 Mon Sep 17 00:00:00 2001 From: Roland Lutz Date: Mon, 14 Aug 2017 13:10:57 +0200 Subject: [PATCH 5/7] icemulti: Refuse to pack empty image --- icemulti/icemulti.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/icemulti/icemulti.cc b/icemulti/icemulti.cc index 42b4dcb08db..5c5f24cc346 100644 --- a/icemulti/icemulti.cc +++ b/icemulti/icemulti.cc @@ -109,6 +109,9 @@ size_t Image::size() ifs.seekg (0, ifs.beg); if (ifs.fail()) error("can't seek on input image `%s': %s\n", filename, strerror(errno)); + + if (length == 0) + error("input image `%s' doesn't contain any data\n", filename); return length; } From 395b36f293849585e961de1454acb44058fc44f6 Mon Sep 17 00:00:00 2001 From: Roland Lutz Date: Mon, 10 Jul 2017 14:15:31 +0200 Subject: [PATCH 6/7] icemulti: Use getopt to parse arguments --- icemulti/icemulti.cc | 82 ++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 34 deletions(-) diff --git a/icemulti/icemulti.cc b/icemulti/icemulti.cc index 5c5f24cc346..60b6feafbe6 100644 --- a/icemulti/icemulti.cc +++ b/icemulti/icemulti.cc @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -194,6 +195,8 @@ void usage() int main(int argc, char **argv) { + int c; + char *endptr = NULL; bool coldboot = false; int por_image = 0; int image_count = 0; @@ -203,52 +206,63 @@ int main(int argc, char **argv) std::unique_ptr images[NUM_IMAGES]; const char *outfile_name = NULL; + static struct option long_options[] = { + {NULL, 0, NULL, 0} + }; + program_short_name = strrchr(argv[0], '/'); if (program_short_name == NULL) program_short_name = argv[0]; else program_short_name++; - for (int i = 1; i < argc; i++) - { - if (argv[i][0] == '-' && argv[i][1]) { - for (int j = 1; argv[i][j]; j++) - if (argv[i][j] == 'c') { - coldboot = true; - } else if (argv[i][j] == 'p' && argv[i][j+1]) { - por_image = argv[i][++j] - '0'; - } else if (argv[i][j] == 'a' || argv[i][j] == 'A') { - align_first = argv[i][j] == 'A'; - if (argv[i][j+1]) - align_bits = atoi(&argv[i][j+1]); - else if(i+1 < argc) - align_bits = atoi(argv[++i]); - else - usage(); - break; - } else if (argv[i][j] == 'o') { - if (argv[i][j+1]) - outfile_name = &argv[i][j+1]; - else if(i+1 < argc) - outfile_name = argv[++i]; - else - usage(); - break; - } else if (argv[i][j] == 'v') { - log_level++; - } else - usage(); - continue; + while ((c = getopt_long(argc, argv, "cp:a:A:o:v", + long_options, NULL)) != -1) + switch (c) { + case 'c': + coldboot = true; + break; + case 'p': + if (optarg[0] == '0' && optarg[1] == '\0') + por_image = 0; + else if (optarg[0] == '1' && optarg[1] == '\0') + por_image = 1; + else if (optarg[0] == '2' && optarg[1] == '\0') + por_image = 2; + else if (optarg[0] == '3' && optarg[1] == '\0') + por_image = 3; + else + error("`%s' is not a valid power-on/reset image (must be 0, 1, 2, or 3)\n", optarg); + break; + case 'A': + align_first = true; + /* fallthrough */ + case 'a': + align_bits = strtol(optarg, &endptr, 0); + if (*endptr != '\0') + error("`%s' is not a valid number\n", optarg); + break; + case 'o': + outfile_name = optarg; + break; + case 'v': + log_level++; + break; + default: + usage(); } + if (optind == argc) { + fprintf(stderr, "%s: missing argument\n", program_short_name); + usage(); + } + + while (optind != argc) { if (image_count >= NUM_IMAGES) error("Too many images supplied\n"); - images[image_count++].reset(new Image(argv[i])); + images[image_count++].reset(new Image(argv[optind++])); } - if (!image_count) - usage(); - if (coldboot && por_image != 0) error("Can't select power on reset boot image in cold boot mode\n"); From a9c53a32c06362b4cf8a8fc964884cd7258b52f0 Mon Sep 17 00:00:00 2001 From: Roland Lutz Date: Tue, 11 Jul 2017 17:32:14 +0200 Subject: [PATCH 7/7] icemulti: Check for negative alignment exponent --- icemulti/icemulti.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/icemulti/icemulti.cc b/icemulti/icemulti.cc index 60b6feafbe6..da90da3f42e 100644 --- a/icemulti/icemulti.cc +++ b/icemulti/icemulti.cc @@ -241,6 +241,8 @@ int main(int argc, char **argv) align_bits = strtol(optarg, &endptr, 0); if (*endptr != '\0') error("`%s' is not a valid number\n", optarg); + if (align_bits < 0) + error("argument to `-%c' must be non-negative\n", c); break; case 'o': outfile_name = optarg;