diff options
Diffstat (limited to 'src/tools/imgtool/imgtool.cpp')
-rw-r--r-- | src/tools/imgtool/imgtool.cpp | 228 |
1 files changed, 94 insertions, 134 deletions
diff --git a/src/tools/imgtool/imgtool.cpp b/src/tools/imgtool/imgtool.cpp index b51d7b4d478..e10558dcce1 100644 --- a/src/tools/imgtool/imgtool.cpp +++ b/src/tools/imgtool/imgtool.cpp @@ -8,15 +8,25 @@ ***************************************************************************/ -#include <string.h> -#include <ctype.h> -#include <iostream> - #include "imgtool.h" -#include "formats/imageutl.h" +#include "charconv.h" +#include "filter.h" #include "library.h" #include "modules.h" -#include "pool.h" + +#include "formats/imageutl.h" + +#include "corestr.h" +#include "opresolv.h" +#include "path.h" +#include "strformat.h" + +#include <cstdarg> +#include <cstdio> +#include <cstring> +#include <cctype> +#include <iostream> + /*************************************************************************** @@ -83,10 +93,11 @@ char *strncpyz(char *dest, const char *source, size_t len) // extract_padded_string //------------------------------------------------- -static std::string extract_padded_string(const char *source, size_t len) +static std::string extract_padded_string(const char *source, size_t len, char pad) { - while ((len > 0) && (source[len - 1] == ' ')) + while ((len > 0) && (source[len - 1] == pad)) len--; + return std::string(source, len); } @@ -97,10 +108,10 @@ static std::string extract_padded_string(const char *source, size_t len) // this in common code //------------------------------------------------- -std::string extract_padded_filename(const char *source, size_t filename_length, size_t extension_length) +std::string extract_padded_filename(const char *source, size_t filename_length, size_t extension_length, char pad) { - std::string filename = extract_padded_string(source, filename_length); - std::string extension = extract_padded_string(source + filename_length, extension_length); + std::string filename = extract_padded_string(source, filename_length, pad); + std::string extension = extract_padded_string(source + filename_length, extension_length, pad); return extension.empty() ? filename : filename + "." + extension; } @@ -139,7 +150,7 @@ static imgtoolerr_t markerrorsource(imgtoolerr_t err) static void internal_error(const imgtool_module *module, const char *message) { #ifdef MAME_DEBUG - printf("%s: %s\n", module->name, message); + printf("%s: %s\n", module->name.c_str(), message); #endif } @@ -249,45 +260,39 @@ void imgtool_warn(const char *format, ...) static imgtoolerr_t evaluate_module(const char *fname, const imgtool_module *module, float &result) { imgtoolerr_t err; - imgtool::image::ptr image; - imgtool::partition::ptr partition; - imgtool::directory::ptr imageenum; - imgtool_dirent ent; - float current_result; result = 0.0; + imgtool::image::ptr image; err = imgtool::image::open(module, fname, OSD_FOPEN_READ, image); - if (err) - goto done; - - if (image) + if (!err && image) { - current_result = module->open_is_strict ? 0.9 : 0.5; - + imgtool::partition::ptr partition; + imgtool::directory::ptr imageenum; err = imgtool::partition::open(*image, 0, partition); - if (err) - goto done; + if (!err) + err = imgtool::directory::open(*partition, "", imageenum); - err = imgtool::directory::open(*partition, "", imageenum); - if (err) - goto done; - - memset(&ent, 0, sizeof(ent)); - do + if (!err) { - err = imageenum->get_next(ent); - if (err) - goto done; + float current_result = module->open_is_strict ? 0.9 : 0.5; - if (ent.corrupt) - current_result = (current_result * 99 + 1.00f) / 100; - else - current_result = (current_result + 1.00f) / 2; - } - while(!ent.eof); + imgtool_dirent ent; + do + { + err = imageenum->get_next(ent); + if (err) + goto done; + + if (ent.corrupt) + current_result = (current_result * 99 + 1.00f) / 100; + else + current_result = (current_result + 1.00f) / 2; + } + while (!ent.eof); - result = current_result; + result = current_result; + } } done: @@ -334,7 +339,7 @@ imgtoolerr_t imgtool::image::identify_file(const char *fname, imgtool_module **m /* iterate through all modules */ for (const auto &module : library.modules()) { - if (!extension || image_find_extension(module->extensions, extension)) + if (!extension || image_find_extension(module->extensions.c_str(), extension)) { err = evaluate_module(fname, module.get(), val); if (err) @@ -532,16 +537,6 @@ imgtoolerr_t imgtool::image::list_partitions(std::vector<imgtool::partition_info } -//------------------------------------------------- -// malloc - allocates memory associated with an image -//------------------------------------------------- - -void *imgtool::image::malloc(size_t size) -{ - return pool_malloc_lib(m_pool, size); -} - - /*************************************************************************** Imgtool partition management @@ -588,8 +583,8 @@ imgtool::partition::partition(imgtool::image &image, const imgtool_class &imgcla m_set_attrs = (imgtoolerr_t(*)(imgtool::partition &, const char *, const uint32_t *, const imgtool_attribute *)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_SET_ATTRS); m_attr_name = (imgtoolerr_t(*)(uint32_t, const imgtool_attribute *, char *, size_t)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_ATTR_NAME); m_get_iconinfo = (imgtoolerr_t(*)(imgtool::partition &, const char *, imgtool_iconinfo *)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_GET_ICON_INFO); - m_suggest_transfer = (imgtoolerr_t(*)(imgtool::partition &, const char *, imgtool_transfer_suggestion *, size_t)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_SUGGEST_TRANSFER); - m_get_chain = (imgtoolerr_t(*)(imgtool::partition &, const char *, imgtool_chainent *, size_t)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_GET_CHAIN); + m_suggest_transfer = (imgtoolerr_t(*)(imgtool::partition &, const char *, imgtool::transfer_suggestion *, size_t)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_SUGGEST_TRANSFER); + m_get_chain = (imgtoolerr_t(*)(imgtool::partition &, const char *, imgtool::chainent *, size_t)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_GET_CHAIN); m_writefile_optguide = (const util::option_guide *) imgtool_get_info_ptr(&imgclass, IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE); const char *writefile_optspec = (const char *)imgtool_get_info_ptr(&imgclass, IMGTOOLINFO_STR_WRITEFILE_OPTSPEC); @@ -849,17 +844,17 @@ bool imgtool_validitychecks(void) { features = imgtool_get_module_features(module.get()); - if (!module->name) + if (module->name.empty()) { - util::stream_format(std::wcerr, L"imgtool module %s has null 'name'\n", wstring_from_utf8(module->name)); + util::stream_format(std::wcerr, L"imgtool module has null 'name'\n"); error = true; } - if (!module->description) + if (module->description.empty()) { util::stream_format(std::wcerr, L"imgtool module %s has null 'description'\n", wstring_from_utf8(module->name)); error = true; } - if (!module->extensions) + if (module->extensions.empty()) { util::stream_format(std::wcerr, L"imgtool module %s has null 'extensions'\n", wstring_from_utf8(module->extensions)); error = true; @@ -893,24 +888,24 @@ bool imgtool_validitychecks(void) #endif /* sanity checks on creation options */ - if (module->createimage_optguide || module->createimage_optspec) + if (module->createimage_optguide || !module->createimage_optspec.empty()) { if (!module->create) { util::stream_format(std::wcerr, L"imgtool module %s has creation options without supporting create\n", wstring_from_utf8(module->name)); error = true; } - if ((!module->createimage_optguide && module->createimage_optspec) - || (module->createimage_optguide && !module->createimage_optspec)) + if ((!module->createimage_optguide && !module->createimage_optspec.empty()) + || (module->createimage_optguide && module->createimage_optspec.empty())) { - util::stream_format(std::wcerr, L"imgtool module %s does has partially incomplete creation options\n", wstring_from_utf8(module->name)); + util::stream_format(std::wcerr, L"imgtool module %s has partially incomplete creation options\n", wstring_from_utf8(module->name)); error = true; } - if (module->createimage_optguide && module->createimage_optspec) + if (module->createimage_optguide && !module->createimage_optspec.empty()) { auto resolution = std::make_unique<util::option_resolution>(*module->createimage_optguide); - resolution->set_specification(module->createimage_optspec); + resolution->set_specification(module->createimage_optspec.c_str()); } } } @@ -936,7 +931,7 @@ char *imgtool_temp_str(void) { static int index; static char temp_string_pool[32][256]; - return temp_string_pool[index++ % ARRAY_LENGTH(temp_string_pool)]; + return temp_string_pool[index++ % std::size(temp_string_pool)]; } @@ -953,8 +948,6 @@ imgtoolerr_t imgtool::image::internal_open(const imgtool_module *module, const s imgtoolerr_t err; imgtool::stream::ptr stream; imgtool::image::ptr image; - object_pool *pool = nullptr; - void *extra_bytes = nullptr; outimg.reset(); @@ -965,14 +958,6 @@ imgtoolerr_t imgtool::image::internal_open(const imgtool_module *module, const s goto done; } - // create a memory pool - pool = pool_alloc_lib(nullptr); - if (!pool) - { - err = imgtoolerr_t(IMGTOOLERR_OUTOFMEMORY); - goto done; - } - // open the stream stream = imgtool::stream::open(filename, read_or_write); if (!stream) @@ -981,29 +966,14 @@ imgtoolerr_t imgtool::image::internal_open(const imgtool_module *module, const s goto done; } - // allocate extra - if (module->image_extra_bytes > 0) - { - extra_bytes = pool_malloc_lib(pool, module->image_extra_bytes); - if (!extra_bytes) - { - err = imgtoolerr_t(IMGTOOLERR_OUTOFMEMORY); - goto done; - } - memset(extra_bytes, 0, module->image_extra_bytes); - } - // setup the image structure - try { image = std::make_unique<imgtool::image>(*module, pool, extra_bytes); } + try { image = std::make_unique<imgtool::image>(*module); } catch (std::bad_alloc const &) { err = imgtoolerr_t(IMGTOOLERR_OUTOFMEMORY); goto done; } - // the pool is no longer owned by this function - pool = nullptr; - // actually call create or open err = (read_or_write == OSD_FOPEN_RW_CREATE) ? module->create(*image, std::move(stream), createopts) @@ -1020,8 +990,6 @@ imgtoolerr_t imgtool::image::internal_open(const imgtool_module *module, const s outimg = std::move(image); done: - if (pool) - pool_free_lib(pool); return err; } @@ -1057,12 +1025,16 @@ imgtoolerr_t imgtool::image::open(const std::string &modulename, const std::stri // imgtool::image::image //------------------------------------------------- -imgtool::image::image(const imgtool_module &module, object_pool *pool, void *extra_bytes) +imgtool::image::image(const imgtool_module &module) : m_module(module) - , m_pool(pool) - , m_extra_bytes(extra_bytes) , m_okay_to_close(false) { + if (module.image_extra_bytes > 0) + { + m_extra_bytes = std::make_unique<uint8_t[]>(module.image_extra_bytes); + std::fill_n(&m_extra_bytes[0], module.image_extra_bytes, 0); + } + } @@ -1074,7 +1046,6 @@ imgtool::image::~image() { if (m_okay_to_close && module().close) module().close(*this); - pool_free_lib(m_pool); } @@ -1093,8 +1064,8 @@ imgtoolerr_t imgtool::image::create(const imgtool_module *module, const std::str try { alloc_resolution.reset(new util::option_resolution(*module->createimage_optguide)); } catch (...) { return (imgtoolerr_t)IMGTOOLERR_OUTOFMEMORY; } - if (module->createimage_optspec) - alloc_resolution->set_specification(module->createimage_optspec); + if (!module->createimage_optspec.empty()) + alloc_resolution->set_specification(module->createimage_optspec.c_str()); opts = alloc_resolution.get(); } @@ -1316,37 +1287,31 @@ done: imgtoolerr_t imgtool::partition::get_file_size(const char *fname, uint64_t &filesize) { imgtoolerr_t err; - imgtool::directory::ptr imgenum; - imgtool_dirent ent; - const char *path; - - path = nullptr; /* TODO: Need to parse off the path */ - filesize = ~((uint64_t) 0); - memset(&ent, 0, sizeof(ent)); + filesize = ~uint64_t(0); + imgtool::directory::ptr imgenum; + const char *path = nullptr; // TODO: Need to parse off the path err = imgtool::directory::open(*this, path, imgenum); if (err) - goto done; + return err; + imgtool_dirent ent; do { err = imgenum->get_next(ent); if (err) - goto done; + return err; if (!core_stricmp(fname, ent.filename)) { filesize = ent.filesize; - goto done; + return err; } } while(ent.filename[0]); - err = (imgtoolerr_t)IMGTOOLERR_FILENOTFOUND; - -done: - return err; + return (imgtoolerr_t)IMGTOOLERR_FILENOTFOUND; } @@ -1489,12 +1454,10 @@ imgtoolerr_t imgtool::partition::get_icon_info(const char *path, imgtool_iconinf //------------------------------------------------- imgtoolerr_t imgtool::partition::suggest_file_filters(const char *path, - imgtool::stream *stream, imgtool_transfer_suggestion *suggestions, size_t suggestions_length) + imgtool::stream *stream, imgtool::transfer_suggestion *suggestions, size_t suggestions_length) { imgtoolerr_t err; - int i, j; - imgtoolerr_t (*check_stream)(imgtool::stream &stream, imgtool_suggestion_viability_t *viability); - size_t position; + imgtoolerr_t (*check_stream)(imgtool::stream &stream, imgtool::suggestion_viability_t *viability); // clear out buffer memset(suggestions, 0, sizeof(*suggestions) * suggestions_length); @@ -1516,15 +1479,15 @@ imgtoolerr_t imgtool::partition::suggest_file_filters(const char *path, // loop on resulting suggestions, and do the following: // 1. Call check_stream if present, and remove disqualified streams // 2. Fill in missing descriptions - i = j = 0; + int i = 0, j = 0; while(suggestions[i].viability) { if (stream && suggestions[i].filter) { - check_stream = (imgtoolerr_t (*)(imgtool::stream &, imgtool_suggestion_viability_t *)) filter_get_info_fct(suggestions[i].filter, FILTINFO_PTR_CHECKSTREAM); + check_stream = (imgtoolerr_t (*)(imgtool::stream &, imgtool::suggestion_viability_t *)) filter_get_info_fct(suggestions[i].filter, FILTINFO_PTR_CHECKSTREAM); if (check_stream) { - position = stream->tell(); + size_t const position = stream->tell(); err = check_stream(*stream, &suggestions[i].viability); stream->seek(position, SEEK_SET); if (err) @@ -1552,7 +1515,7 @@ imgtoolerr_t imgtool::partition::suggest_file_filters(const char *path, } i++; } - suggestions[j].viability = (imgtool_suggestion_viability_t)0; + suggestions[j].viability = (imgtool::suggestion_viability_t)0; return IMGTOOLERR_SUCCESS; } @@ -1563,17 +1526,15 @@ imgtoolerr_t imgtool::partition::suggest_file_filters(const char *path, // chain for a file or directory on a partition //------------------------------------------------- -imgtoolerr_t imgtool::partition::get_chain(const char *path, imgtool_chainent *chain, size_t chain_size) +imgtoolerr_t imgtool::partition::get_chain(const char *path, imgtool::chainent *chain, size_t chain_size) { - size_t i; - assert(chain_size > 0); if (!m_get_chain) return imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); // initialize the chain array, so the module's get_chain function can be lazy - for (i = 0; i < chain_size; i++) + for (int i = 0; i < chain_size; i++) { chain[i].level = 0; chain[i].block = ~0; @@ -1592,7 +1553,7 @@ imgtoolerr_t imgtool::partition::get_chain(const char *path, imgtool_chainent *c imgtoolerr_t imgtool::partition::get_chain_string(const char *path, char *buffer, size_t buffer_len) { imgtoolerr_t err; - imgtool_chainent chain[512]; + imgtool::chainent chain[512]; uint64_t last_block; uint8_t cur_level = 0; int len, i; @@ -1602,7 +1563,7 @@ imgtoolerr_t imgtool::partition::get_chain_string(const char *path, char *buffer chain[0].block = ~0; last_block = chain[0].block; - err = get_chain(path, chain, ARRAY_LENGTH(chain)); + err = get_chain(path, chain, std::size(chain)); if (err) return err; @@ -1883,7 +1844,7 @@ imgtoolerr_t imgtool::partition::put_file(const char *newfname, const char *fork if (!newfname) { - basename = core_filename_extract_base(source); + basename = std::string(core_filename_extract_base(source)); newfname = basename.c_str(); } @@ -2276,7 +2237,7 @@ imgtool::directory::directory(imgtool::partition &partition) if (partition.m_directory_extra_bytes > 0) { m_extra_bytes = std::make_unique<uint8_t[]>(partition.m_directory_extra_bytes); - memset(m_extra_bytes.get(), 0, sizeof(m_extra_bytes.get()[0] * partition.m_directory_extra_bytes)); + memset(m_extra_bytes.get(), 0, sizeof(m_extra_bytes[0]) * partition.m_directory_extra_bytes); } } @@ -2341,9 +2302,8 @@ imgtoolerr_t imgtool::directory::get_next(imgtool_dirent &ent) { imgtoolerr_t err; - // This makes it so that drivers don't have to take care of clearing - // the attributes if they don't apply - memset(&ent, 0, sizeof(ent)); + // This makes it so that drivers don't have to take care of clearing the attributes if they don't apply + ent = imgtool_dirent(); err = m_partition.m_next_enum(*this, ent); if (err) @@ -2361,7 +2321,7 @@ imgtoolerr_t imgtool::directory::get_next(imgtool_dirent &ent) { return imgtoolerr_t(IMGTOOLERR_BADFILENAME); } - snprintf(ent.filename, ARRAY_LENGTH(ent.filename), "%s", new_fname.c_str()); + snprintf(ent.filename, std::size(ent.filename), "%s", new_fname.c_str()); } // don't trust the module! @@ -2393,7 +2353,7 @@ void unknown_partition_get_info(const imgtool_class *imgclass, uint32_t state, u { switch(state) { - /* --- the following bits of info are returned as NULL-terminated strings --- */ + /* --- the following bits of info are returned as NUL-terminated strings --- */ case IMGTOOLINFO_STR_NAME: strcpy(info->s = imgtool_temp_str(), "unknown"); break; case IMGTOOLINFO_STR_DESCRIPTION: strcpy(info->s = imgtool_temp_str(), "Unknown partition type"); break; } |