summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Nathan Woods <npwoods@mess.org>2016-08-27 16:41:11 -0400
committer Nathan Woods <npwoods@mess.org>2016-08-27 16:41:11 -0400
commitb60879e595edc98fb12b7990bd3b45188191bbf1 (patch)
tree9e7a73afa998ca920b407f9c4fd016a2c7c94cdc
parent89737886e05e6f9ebc254a47865c3c2335357f1a (diff)
option_guide C++-ification, touched up imgtool
The main point of this change is to C++-ify option_guide. It was changed from a struct array to a class, namespaced etc, with the ultimate hope of incorporating an in-emulation image creation UI. Imgtool got hit with a number of changes; I'll probably have to bring that off of the backburner and touch that up too
-rw-r--r--src/devices/imagedev/diablo.cpp2
-rw-r--r--src/devices/imagedev/diablo.h2
-rw-r--r--src/devices/imagedev/flopdrv.h2
-rw-r--r--src/devices/imagedev/harddriv.cpp2
-rw-r--r--src/devices/imagedev/harddriv.h2
-rw-r--r--src/emu/diimage.cpp10
-rw-r--r--src/emu/diimage.h4
-rw-r--r--src/lib/formats/flopimg.cpp47
-rw-r--r--src/lib/util/opresolv.cpp693
-rw-r--r--src/lib/util/opresolv.h201
-rw-r--r--src/mame/machine/psion_pack.cpp2
-rw-r--r--src/mame/machine/psion_pack.h2
-rw-r--r--src/tools/imgtool/iflopimg.cpp2
-rw-r--r--src/tools/imgtool/imghd.cpp2
-rw-r--r--src/tools/imgtool/imgtool.cpp58
-rw-r--r--src/tools/imgtool/library.cpp2
-rw-r--r--src/tools/imgtool/library.h6
-rw-r--r--src/tools/imgtool/main.cpp110
-rw-r--r--src/tools/imgtool/modules/amiga.cpp10
-rw-r--r--src/tools/imgtool/modules/bml3.cpp2
-rw-r--r--src/tools/imgtool/modules/cybiko.cpp2
-rw-r--r--src/tools/imgtool/modules/hp48.cpp2
-rw-r--r--src/tools/imgtool/modules/pc_hard.cpp2
-rw-r--r--src/tools/imgtool/modules/psion.cpp4
-rw-r--r--src/tools/imgtool/modules/rsdos.cpp2
-rw-r--r--src/tools/imgtool/modules/thomson.cpp8
-rw-r--r--src/tools/imgtool/modules/ti99.cpp6
-rw-r--r--src/tools/imgtool/modules/ti990hd.cpp2
-rw-r--r--src/tools/imgtool/modules/vzdos.cpp2
29 files changed, 552 insertions, 639 deletions
diff --git a/src/devices/imagedev/diablo.cpp b/src/devices/imagedev/diablo.cpp
index 413d4c6b9b5..5009c0fc872 100644
--- a/src/devices/imagedev/diablo.cpp
+++ b/src/devices/imagedev/diablo.cpp
@@ -62,7 +62,7 @@ void diablo_image_device::device_config_complete()
update_names();
}
-const option_guide *diablo_image_device::create_option_guide() const
+const util::option_guide &diablo_image_device::create_option_guide() const
{
return dsk_option_guide;
}
diff --git a/src/devices/imagedev/diablo.h b/src/devices/imagedev/diablo.h
index 8ab2ac1addc..f4d99532345 100644
--- a/src/devices/imagedev/diablo.h
+++ b/src/devices/imagedev/diablo.h
@@ -45,7 +45,7 @@ public:
virtual bool is_reset_on_load() const override { return 0; }
virtual const char *image_interface() const override { return m_interface; }
virtual const char *file_extensions() const override { return "chd,dsk"; }
- virtual const option_guide *create_option_guide() const override;
+ virtual const util::option_guide &create_option_guide() const override;
// specific implementation
hard_disk_file *get_hard_disk_file() { return m_hard_disk_handle; }
diff --git a/src/devices/imagedev/flopdrv.h b/src/devices/imagedev/flopdrv.h
index 34e54100364..c362d62aa9e 100644
--- a/src/devices/imagedev/flopdrv.h
+++ b/src/devices/imagedev/flopdrv.h
@@ -114,7 +114,7 @@ public:
virtual bool is_reset_on_load() const override { return 0; }
virtual const char *image_interface() const override;
virtual const char *file_extensions() const override { return m_extension_list; }
- virtual const option_guide *create_option_guide() const override { return floppy_option_guide; }
+ virtual const util::option_guide &create_option_guide() const override { return floppy_option_guide; }
floppy_image_legacy *flopimg_get_image();
void floppy_drive_set_geometry(floppy_type_t type);
diff --git a/src/devices/imagedev/harddriv.cpp b/src/devices/imagedev/harddriv.cpp
index 3e7cb789552..ffc17871050 100644
--- a/src/devices/imagedev/harddriv.cpp
+++ b/src/devices/imagedev/harddriv.cpp
@@ -85,7 +85,7 @@ void harddisk_image_device::device_config_complete()
update_names();
}
-const option_guide *harddisk_image_device::create_option_guide() const
+const util::option_guide &harddisk_image_device::create_option_guide() const
{
return hd_option_guide;
}
diff --git a/src/devices/imagedev/harddriv.h b/src/devices/imagedev/harddriv.h
index d2ce6aeaef9..2438262690c 100644
--- a/src/devices/imagedev/harddriv.h
+++ b/src/devices/imagedev/harddriv.h
@@ -47,7 +47,7 @@ public:
virtual bool is_reset_on_load() const override { return 0; }
virtual const char *image_interface() const override { return m_interface; }
virtual const char *file_extensions() const override { return "chd,hd"; }
- virtual const option_guide *create_option_guide() const override;
+ virtual const util::option_guide &create_option_guide() const override;
// specific implementation
hard_disk_file *get_hard_disk_file() { return m_hard_disk_handle; }
diff --git a/src/emu/diimage.cpp b/src/emu/diimage.cpp
index a989d86922d..6602ba199a2 100644
--- a/src/emu/diimage.cpp
+++ b/src/emu/diimage.cpp
@@ -1224,6 +1224,16 @@ void device_image_interface::unload()
//-------------------------------------------------
+// create_option_guide
+//-------------------------------------------------
+
+const util::option_guide &device_image_interface::create_option_guide() const
+{
+ static const util::option_guide null_option_guide = {};
+ return null_option_guide;
+}
+
+//-------------------------------------------------
// update_names - update brief and instance names
//-------------------------------------------------
diff --git a/src/emu/diimage.h b/src/emu/diimage.h
index 3ec5f46a52a..8de166e1a4b 100644
--- a/src/emu/diimage.h
+++ b/src/emu/diimage.h
@@ -160,11 +160,11 @@ public:
virtual bool is_reset_on_load() const = 0;
virtual const char *image_interface() const { return nullptr; }
virtual const char *file_extensions() const = 0;
- virtual const option_guide *create_option_guide() const { return nullptr; }
+ virtual const util::option_guide &create_option_guide() const;
const image_device_format *device_get_indexed_creatable_format(int index) const { if (index < m_formatlist.size()) return m_formatlist.at(index).get(); else return nullptr; }
const image_device_format *device_get_named_creatable_format(const std::string &format_name);
- const option_guide *device_get_creation_option_guide() const { return create_option_guide(); }
+ const util::option_guide &device_get_creation_option_guide() const { return create_option_guide(); }
const char *error();
void seterror(image_error_t err, const char *message);
diff --git a/src/lib/formats/flopimg.cpp b/src/lib/formats/flopimg.cpp
index 48240973d3a..6ffa7bd6cc2 100644
--- a/src/lib/formats/flopimg.cpp
+++ b/src/lib/formats/flopimg.cpp
@@ -204,35 +204,9 @@ floperr_t floppy_open_choices(void *fp, const struct io_procs *procs, const std:
-static floperr_t option_to_floppy_error(util::option_resolution::error oerr)
-{
- floperr_t err;
- switch(oerr) {
- case util::option_resolution::error::SUCCESS:
- err = FLOPPY_ERROR_SUCCESS;
- break;
- case util::option_resolution::error::OUTOFMEMORY:
- err = FLOPPY_ERROR_OUTOFMEMORY;
- break;
- case util::option_resolution::error::PARAMOUTOFRANGE:
- case util::option_resolution::error::PARAMNOTSPECIFIED:
- case util::option_resolution::error::PARAMNOTFOUND:
- case util::option_resolution::error::PARAMALREADYSPECIFIED:
- case util::option_resolution::error::BADPARAM:
- case util::option_resolution::error::SYNTAX:
- default:
- err = FLOPPY_ERROR_INTERNAL;
- break;
- };
- return err;
-}
-
-
-
floperr_t floppy_create(void *fp, const struct io_procs *procs, const struct FloppyFormat *format, util::option_resolution *parameters, floppy_image_legacy **outfloppy)
{
floppy_image_legacy *floppy = nullptr;
- util::option_resolution::error oerr;
floperr_t err;
int heads, tracks, h, t;
std::unique_ptr<util::option_resolution> alloc_resolution;
@@ -250,26 +224,16 @@ floperr_t floppy_create(void *fp, const struct io_procs *procs, const struct Flo
/* if this format expects creation parameters and none were specified, create some */
if (!parameters && format->param_guidelines)
{
- alloc_resolution = std::make_unique<util::option_resolution>(floppy_option_guide, format->param_guidelines);
+ alloc_resolution = std::make_unique<util::option_resolution>(floppy_option_guide);
if (!alloc_resolution)
{
err = FLOPPY_ERROR_OUTOFMEMORY;
goto done;
}
+ alloc_resolution->set_specification(format->param_guidelines);
parameters = alloc_resolution.get();
}
- /* finish the parameters, if specified */
- if (parameters)
- {
- oerr = parameters->finish();
- if (oerr != util::option_resolution::error::SUCCESS)
- {
- err = option_to_floppy_error(oerr);
- goto done;
- }
- }
-
/* call the format constructor */
err = format->construct(floppy, format, parameters);
if (err)
@@ -690,17 +654,14 @@ floperr_t floppy_format_track(floppy_image_legacy *floppy, int head, int track,
/* create a dummy resolution; if no parameters were specified */
if (!parameters)
{
- alloc_resolution = std::make_unique<util::option_resolution>(floppy_option_guide, floppy->floppy_option->param_guidelines);
+ alloc_resolution = std::make_unique<util::option_resolution>(floppy_option_guide);
if (!alloc_resolution)
return FLOPPY_ERROR_OUTOFMEMORY;
+ alloc_resolution->set_specification(floppy->floppy_option->param_guidelines);
parameters = alloc_resolution.get();
}
- auto oerr = parameters->finish();
- if (oerr != util::option_resolution::error::SUCCESS)
- return option_to_floppy_error(oerr);
-
err = format->format_track(floppy, head, track, parameters);
if (err)
return err;
diff --git a/src/lib/util/opresolv.cpp b/src/lib/util/opresolv.cpp
index baf66580d26..fa6e1fa0f28 100644
--- a/src/lib/util/opresolv.cpp
+++ b/src/lib/util/opresolv.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Nathan Woods
/****************************************************************************
- opresolv.h
+ opresolv.cpp
Extensible ranged option resolution handling
@@ -19,546 +19,465 @@
namespace util {
+
/***************************************************************************
- option_resolution
+ option_resolution
***************************************************************************/
// -------------------------------------------------
-// entry::int_value
-// -------------------------------------------------
-
-int option_resolution::entry::int_value() const
-{
- return atoi(value.c_str());
-}
-
-
-// -------------------------------------------------
-// entry::set_int_value
-// -------------------------------------------------
-
-void option_resolution::entry::set_int_value(int i)
-{
- value = string_format("%d", i);
-}
-
-
-// -------------------------------------------------
-// resolve_single_param
+// ctor
// -------------------------------------------------
-option_resolution::error option_resolution::resolve_single_param(const char *specification, option_resolution::entry *param_value,
- struct range *range, size_t range_count)
+option_resolution::option_resolution(const option_guide &guide)
{
- int FLAG_IN_RANGE = 0x01;
- int FLAG_IN_DEFAULT = 0x02;
- int FLAG_DEFAULT_SPECIFIED = 0x04;
- int FLAG_HALF_RANGE = 0x08;
-
- int last_value = 0;
- int value = 0;
- int flags = 0;
- const char *s = specification;
+ // reserve space for entries
+ m_entries.reserve(guide.entries().size());
- while(*s && !isalpha(*s))
+ // initialize each of the entries; can't use foreach because we need to scan the
+ // ENUM_VALUE entries
+ for (auto iter = guide.entries().cbegin(); iter != guide.entries().cend(); iter++)
{
- if (*s == '-')
- {
- /* range specifier */
- if (flags & (FLAG_IN_RANGE|FLAG_IN_DEFAULT))
- {
- return error::SYNTAX;
- }
- flags |= FLAG_IN_RANGE;
- s++;
+ // create the entry
+ m_entries.emplace_back(*iter);
+ entry &entry(m_entries.back());
- if (range)
- {
- range->max = -1;
- if ((flags & FLAG_HALF_RANGE) == 0)
- {
- range->min = -1;
- flags |= FLAG_HALF_RANGE;
- }
- }
- }
- else if (*s == '[')
- {
- /* begin default value */
- if (flags & (FLAG_IN_DEFAULT|FLAG_DEFAULT_SPECIFIED))
- {
- return error::SYNTAX;
- }
- flags |= FLAG_IN_DEFAULT;
- s++;
- }
- else if (*s == ']')
+ // if this is an enumeration, identify the values
+ if (iter->type() == option_guide::entry::option_type::ENUM_BEGIN)
{
- /* end default value */
- if ((flags & FLAG_IN_DEFAULT) == 0)
- {
- return error::SYNTAX;
- }
- flags &= ~FLAG_IN_DEFAULT;
- flags |= FLAG_DEFAULT_SPECIFIED;
- s++;
+ // enum values begin after the ENUM_BEGIN
+ auto enum_value_begin = iter + 1;
+ auto enum_value_end = enum_value_begin;
- if (param_value && param_value->int_value() == -1)
- param_value->set_int_value(value);
- }
- else if (*s == '/')
- {
- /* value separator */
- if (flags & (FLAG_IN_DEFAULT|FLAG_IN_RANGE))
+ // and identify all entries of type ENUM_VALUE
+ while (enum_value_end != guide.entries().end() && enum_value_end->type() == option_guide::entry::option_type::ENUM_VALUE)
{
- return error::SYNTAX;
+ iter++;
+ enum_value_end++;
}
- s++;
- /* if we are spitting out ranges, complete the range */
- if (range && (flags & FLAG_HALF_RANGE))
- {
- range++;
- flags &= ~FLAG_HALF_RANGE;
- if (--range_count == 0)
- range = nullptr;
- }
- }
- else if (*s == ';')
- {
- /* basic separator */
- s++;
- }
- else if (isdigit(*s))
- {
- /* numeric value */
- last_value = value;
- value = 0;
- do
- {
- value *= 10;
- value += *s - '0';
- s++;
- }
- while(isdigit(*s));
-
- if (range)
- {
- if ((flags & FLAG_HALF_RANGE) == 0)
- {
- range->min = value;
- flags |= FLAG_HALF_RANGE;
- }
- range->max = value;
- }
-
- // if we have a value; check to see if it is out of range
- if (param_value && (param_value->int_value() != -1) && (param_value->int_value() != value))
- {
- if ((last_value < param_value->int_value()) && (param_value->int_value() < value))
- {
- if ((flags & FLAG_IN_RANGE) == 0)
- return error::PARAMOUTOFRANGE;
- }
- }
- flags &= ~FLAG_IN_RANGE;
- }
- else
- {
- return error::SYNTAX;
+ // set the range
+ entry.set_enum_value_range(enum_value_begin, enum_value_end);
}
}
+}
- // we can't have zero length guidelines strings
- if (s == specification)
- {
- return error::SYNTAX;
- }
- return error::SUCCESS;
+// -------------------------------------------------
+// dtor
+// -------------------------------------------------
+
+option_resolution::~option_resolution()
+{
}
// -------------------------------------------------
-// lookup_in_specification
+// lookup_in_specification
// -------------------------------------------------
-const char *option_resolution::lookup_in_specification(const char *specification, const option_guide *option)
+const char *option_resolution::lookup_in_specification(const char *specification, const option_guide::entry &option)
{
const char *s;
- s = strchr(specification, option->parameter);
+ s = strchr(specification, option.parameter());
return s ? s + 1 : nullptr;
}
// -------------------------------------------------
-// ctor
+// set_specification - sets the option specification
+// and mutates values accordingly
// -------------------------------------------------
-option_resolution::option_resolution(const option_guide *guide, const char *specification)
+void option_resolution::set_specification(const std::string &specification)
{
- const option_guide *guide_entry;
- int option_count;
- int opt = -1;
-
- assert(guide);
-
- // first count the number of options specified in the guide
- option_count = count_options(guide, specification);
+ for (auto &entry : m_entries)
+ {
+ // find this entry's info in the specification
+ auto entry_specification = lookup_in_specification(specification.c_str(), entry.m_guide_entry);
- // set up the entries list
- m_specification = specification;
- m_entries.resize(option_count);
+ // parse this entry's specification (e.g. - set up ranges and defaults)
+ entry.parse_specification(entry_specification);
- // initialize each of the entries
- opt = 0;
- guide_entry = guide;
- while(guide_entry->option_type != OPTIONTYPE_END)
- {
- switch(guide_entry->option_type)
+ // is this a range typed that needs to be defaulted for the first time?
+ if (entry.is_pertinent() && entry.is_ranged() && entry.value().empty())
{
- case OPTIONTYPE_INT:
- case OPTIONTYPE_ENUM_BEGIN:
- case OPTIONTYPE_STRING:
- if (lookup_in_specification(specification, guide_entry))
- m_entries[opt++].guide_entry = guide_entry;
- break;
-
- case OPTIONTYPE_ENUM_VALUE:
- break;
-
- default:
- assert(false && "Invalid option type");
- break;
+ entry.set_value(entry.default_value());
}
- guide_entry++;
}
- assert(opt == option_count);
}
// -------------------------------------------------
-// dtor
+// find
// -------------------------------------------------
-option_resolution::~option_resolution()
+option_resolution::entry *option_resolution::find(int parameter)
{
+ auto iter = std::find_if(
+ m_entries.begin(),
+ m_entries.end(),
+ [&](const entry &e) { return e.parameter() == parameter; });
+
+ return iter != m_entries.end()
+ ? &*iter
+ : nullptr;
}
// -------------------------------------------------
-// add_param
+// find
// -------------------------------------------------
-option_resolution::error option_resolution::add_param(const char *param, const std::string &value)
+option_resolution::entry *option_resolution::find(const std::string &identifier)
{
- int i;
- bool must_resolve;
- error err;
- const char *option_specification;
- entry *entry = nullptr;
+ auto iter = std::find_if(
+ m_entries.begin(),
+ m_entries.end(),
+ [&](const entry &e) { return !strcmp(e.identifier(), identifier.c_str()); });
+
+ return iter != m_entries.end()
+ ? &*iter
+ : nullptr;
+}
- for(auto &this_entry : m_entries)
- {
- if (!strcmp(param, this_entry.guide_entry->identifier))
- {
- entry = &this_entry;
- break;
- }
- }
- if (entry == nullptr)
- return error::PARAMNOTFOUND;
-
- if (entry->state != entry_state::UNSPECIFIED)
- return error::PARAMALREADYSPECIFIED;
-
- switch(entry->guide_entry->option_type) {
- case OPTIONTYPE_INT:
- entry->set_int_value(atoi(value.c_str()));
- entry->state = entry_state::SPECIFIED;
- must_resolve = true;
- break;
-
- case OPTIONTYPE_STRING:
- entry->value = value;
- entry->state = entry_state::SPECIFIED;
- must_resolve = false;
- break;
-
- case OPTIONTYPE_ENUM_BEGIN:
- for (i = 1; entry->guide_entry[i].option_type == OPTIONTYPE_ENUM_VALUE; i++)
- {
- if (!core_stricmp(value.c_str(), entry->guide_entry[i].identifier))
- {
- entry->set_int_value(entry->guide_entry[i].parameter);
- entry->state = entry_state::SPECIFIED;
- break;
- }
- }
- if (entry->state != entry_state::SPECIFIED)
- return error::BADPARAM;
- must_resolve = true;
- break;
+// -------------------------------------------------
+// lookup_int
+// -------------------------------------------------
- default:
- assert(0);
- return error::INTERNAL;
- }
+int option_resolution::lookup_int(int parameter)
+{
+ auto entry = find(parameter);
+ assert(entry != nullptr);
+ return entry->value_int();
+}
- // do a resolution step if necessary
- if (must_resolve)
- {
- option_specification = lookup_in_specification(m_specification, entry->guide_entry);
- err = resolve_single_param(option_specification, entry, nullptr, 0);
- if (err != error::SUCCESS)
- return err;
-
- // did we not get a real value?
- if (entry->int_value() < 0)
- return error::PARAMNOTSPECIFIED;
- }
- return error::SUCCESS;
+// -------------------------------------------------
+// lookup_string
+// -------------------------------------------------
+
+const std::string &option_resolution::lookup_string(int parameter)
+{
+ auto entry = find(parameter);
+ assert(entry != nullptr);
+ return entry->value();
}
// -------------------------------------------------
-// finish
+// error_string
// -------------------------------------------------
-option_resolution::error option_resolution::finish()
+option_resolution::error option_resolution::get_default(const char *specification, int option_char, int *val)
{
- const char *option_specification;
- error err;
-
- for (auto &entry : m_entries)
- {
- if (entry.state == entry_state::UNSPECIFIED)
- {
- switch(entry.guide_entry->option_type) {
- case OPTIONTYPE_INT:
- case OPTIONTYPE_ENUM_BEGIN:
- option_specification = lookup_in_specification(m_specification, entry.guide_entry);
- assert(option_specification);
- entry.set_int_value(-1);
- err = resolve_single_param(option_specification, &entry, nullptr, 0);
- if (err != error::SUCCESS)
- return err;
- break;
-
- case OPTIONTYPE_STRING:
- entry.value = "";
- break;
-
- default:
- assert(FALSE);
- return error::INTERNAL;
- }
- entry.state = entry_state::SPECIFIED;
- }
- }
- return error::SUCCESS;
+ // NYI
+ return error::INTERNAL;
}
// -------------------------------------------------
-// lookup_entry
+// error_string
// -------------------------------------------------
-const option_resolution::entry *option_resolution::lookup_entry(int option_char) const
+const char *option_resolution::error_string(option_resolution::error err)
{
- for (auto &entry : m_entries)
+ switch (err)
{
- switch(entry.guide_entry->option_type) {
- case OPTIONTYPE_INT:
- case OPTIONTYPE_STRING:
- case OPTIONTYPE_ENUM_BEGIN:
- if (entry.guide_entry->parameter == option_char)
- return &entry;
- break;
-
- default:
- assert(FALSE);
- return nullptr;
- }
+ case error::SUCCESS: return "The operation completed successfully";
+ case error::OUTOFMEMORY: return "Out of memory";
+ case error::PARAMOUTOFRANGE: return "Parameter out of range";
+ case error::PARAMNOTSPECIFIED: return "Parameter not specified";
+ case error::PARAMNOTFOUND: return "Unknown parameter";
+ case error::PARAMALREADYSPECIFIED: return "Parameter specified multiple times";
+ case error::BADPARAM: return "Invalid parameter";
+ case error::SYNTAX: return "Syntax error";
+ case error::INTERNAL: return "Internal error";
}
return nullptr;
}
// -------------------------------------------------
-// lookup_int
+// entry::ctor
// -------------------------------------------------
-int option_resolution::lookup_int(int option_char) const
+option_resolution::entry::entry(const option_guide::entry &guide_entry)
+ : m_guide_entry(guide_entry), m_is_pertinent(false)
{
- auto entry = lookup_entry(option_char);
- return entry ? entry->int_value() : -1;
}
// -------------------------------------------------
-// lookup_string
+// entry::set_enum_value_range
// -------------------------------------------------
-const char *option_resolution::lookup_string(int option_char) const
+void option_resolution::entry::set_enum_value_range(option_guide::entrylist::const_iterator begin, option_guide::entrylist::const_iterator end)
{
- auto entry = lookup_entry(option_char);
- return entry ? entry->value.c_str() : nullptr;
+ m_enum_value_begin = begin;
+ m_enum_value_end = end;
}
// -------------------------------------------------
-// find_option
+// entry::parse_specification
// -------------------------------------------------
-const option_guide *option_resolution::find_option(int option_char) const
+void option_resolution::entry::parse_specification(const char *specification)
{
- auto entry = lookup_entry(option_char);
- return entry ? entry->guide_entry : nullptr;
+ // clear some items out
+ m_ranges.clear();
+ m_default_value.clear();
+
+ // is this even pertinent?
+ m_is_pertinent = (specification != nullptr) && (specification[0] != '\0');
+ if (m_is_pertinent)
+ {
+ int value = 0;
+ bool in_range = false;
+ bool in_default = false;
+ bool default_specified = false;
+ bool half_range = false;
+ size_t pos = 0;
+
+ m_ranges.emplace_back();
+
+ while (specification[pos] && !isalpha(specification[pos]))
+ {
+ if (specification[pos] == '-')
+ {
+ // range specifier
+ assert(!in_range && !in_default && "Syntax error in specification");
+
+ in_range = true;
+ pos++;
+
+ m_ranges.back().max = -1;
+ if (!half_range)
+ {
+ m_ranges.back().min = -1;
+ half_range = true;
+ }
+ }
+ else if (specification[pos] == '[')
+ {
+ // begin default value
+ assert(!in_default && !default_specified && "Syntax error in specification");
+
+ in_default = true;
+ pos++;
+ }
+ else if (specification[pos] == ']')
+ {
+ // end default value
+ assert(in_default && "Syntax error in specification");
+
+ in_default = false;
+ default_specified = true;
+ pos++;
+
+ m_default_value = numeric_value(value);
+ }
+ else if (specification[pos] == '/')
+ {
+ // value separator
+ assert(!in_default && !in_range && "Syntax error in specification");
+ pos++;
+
+ // if we are spitting out ranges, complete the range
+ if (half_range)
+ {
+ m_ranges.emplace_back();
+ half_range = false;
+ }
+ }
+ else if (specification[pos] == ';')
+ {
+ // basic separator
+ pos++;
+ }
+ else if (isdigit(specification[pos]))
+ {
+ // numeric value */
+ value = 0;
+ do
+ {
+ value *= 10;
+ value += specification[pos++] - '0';
+ } while (isdigit(specification[pos]));
+
+ if (!half_range)
+ {
+ m_ranges.back().min = value;
+ half_range = true;
+ }
+ m_ranges.back().max = value;
+ in_range = false;
+ }
+ else
+ {
+ // invalid character
+ assert(false && "Syntax error in specification");
+ }
+ }
+
+ // we can't have zero length guidelines strings
+ assert(pos > 0);
+
+ // appease compiler for scenarios where assert() has been preprocessed out
+ (void)(in_range && in_default && default_specified);
+ }
}
// -------------------------------------------------
-// index_option
+// entry::numeric_value
// -------------------------------------------------
-const option_guide *option_resolution::index_option(int indx) const
+std::string option_resolution::entry::numeric_value(int value)
{
- if ((indx < 0) || (indx >= m_entries.size()))
- return nullptr;
- return m_entries[indx].guide_entry;
+ return string_format("%d", value);
}
// -------------------------------------------------
-// count_options
+// entry::value
// -------------------------------------------------
-size_t option_resolution::count_options(const option_guide *guide, const char *specification)
+const std::string &option_resolution::entry::value() const
{
- size_t option_count = 0;
-
- while(guide->option_type != OPTIONTYPE_END)
- {
- switch(guide->option_type) {
- case OPTIONTYPE_INT:
- case OPTIONTYPE_STRING:
- case OPTIONTYPE_ENUM_BEGIN:
- if (lookup_in_specification(specification, guide))
- option_count++;
- break;
- case OPTIONTYPE_ENUM_VALUE:
- break;
- default:
- assert(FALSE);
- return 0;
- }
- guide++;
- }
- return option_count;
+ static std::string empty_string;
+ return is_pertinent() ? m_value : empty_string;
}
// -------------------------------------------------
-// list_ranges
+// entry::value_int
// -------------------------------------------------
-option_resolution::error option_resolution::list_ranges(const char *specification, int option_char, range *range, size_t range_count)
+int option_resolution::entry::value_int() const
{
- assert(range_count > 0);
+ return is_pertinent() ? atoi(m_value.c_str()) : -1;
+}
- // clear out range
- memset(range, -1, sizeof(*range) * range_count);
- range_count--;
- specification = strchr(specification, option_char);
- if (!specification)
- {
- return error::SYNTAX;
- }
+// -------------------------------------------------
+// entry::set_value
+// -------------------------------------------------
+
+bool option_resolution::entry::set_value(const std::string &value)
+{
+ // reject the value if this isn't pertinent
+ if (!is_pertinent())
+ return false;
+
+ // if this is ranged, check against the ranges
+ if (is_ranged() && find_in_ranges(std::atoi(value.c_str())) == m_ranges.cend())
+ return false;
- return resolve_single_param(specification + 1, nullptr, range, range_count);
+ // looks good! change the value
+ m_value = value;
+ return true;
}
// -------------------------------------------------
-// get_default
+// entry::can_bump_lower
// -------------------------------------------------
-option_resolution::error option_resolution::get_default(const char *specification, int option_char, int *val)
+bool option_resolution::entry::can_bump_lower() const
{
- assert(val);
+ return !m_ranges.empty()
+ && value_int() > m_ranges.front().min;
+}
- // clear out default
- *val = -1;
- specification = strchr(specification, option_char);
- if (!specification)
- {
- return error::SYNTAX;
- }
+// -------------------------------------------------
+// entry::can_bump_higher
+// -------------------------------------------------
- entry ent;
- auto err = resolve_single_param(specification + 1, &ent, nullptr, 0);
- *val = ent.int_value();
- return err;
+bool option_resolution::entry::can_bump_higher() const
+{
+ return !m_ranges.empty()
+ && value_int() < m_ranges.back().max;
}
// -------------------------------------------------
-// list_ranges
+// entry::bump_lower
// -------------------------------------------------
-option_resolution::error option_resolution::is_valid_value(const char *specification, int option_char, int val)
+bool option_resolution::entry::bump_lower()
{
- option_resolution::error err;
- range ranges[256];
- int i;
-
- err = list_ranges(specification, option_char, ranges, ARRAY_LENGTH(ranges));
- if (err != error::SUCCESS)
- return err;
+ auto old_value = value_int();
+ auto current_range = find_in_ranges(old_value);
+ assert(current_range != m_ranges.end());
- for (i = 0; (ranges[i].min >= 0) && (ranges[i].max >= 0); i++)
+ int new_value;
+ if (old_value > current_range->min)
+ {
+ // decrement within current range
+ new_value = old_value - 1;
+ }
+ else if (current_range != m_ranges.begin())
+ {
+ // go to the top of the previous range
+ new_value = (current_range - 1)->max;
+ }
+ else
{
- if ((ranges[i].min <= val) && (ranges[i].max >= val))
- return error::SUCCESS;
+ // at the minimum; don't bump
+ new_value = old_value;
}
- return error::PARAMOUTOFRANGE;
+
+ set_value(new_value);
+ return new_value != old_value;
}
// -------------------------------------------------
-// contains
+// entry::bump_higher
// -------------------------------------------------
-bool option_resolution::contains(const char *specification, int option_char)
+bool option_resolution::entry::bump_higher()
{
- return strchr(specification, option_char) != nullptr;
+ auto old_value = value_int();
+ auto current_range = find_in_ranges(old_value);
+ assert(current_range != m_ranges.end());
+
+ int new_value;
+ if (old_value < current_range->max)
+ {
+ // increment within current range
+ new_value = old_value + 1;
+ }
+ else if (current_range != (m_ranges.end() - 1))
+ {
+ // go to the bottom of the next range
+ new_value = (current_range + 1)->min;
+ }
+ else
+ {
+ // at the minimum; don't bump
+ new_value = old_value;
+ }
+
+ set_value(new_value);
+ return new_value != old_value;
}
// -------------------------------------------------
-// error_string
+// entry::find_in_ranges
// -------------------------------------------------
-const char *option_resolution::error_string(option_resolution::error err)
+option_resolution::entry::rangelist::const_iterator option_resolution::entry::find_in_ranges(int value) const
{
- switch (err)
- {
- case error::SUCCESS: return "The operation completed successfully";
- case error::OUTOFMEMORY: return "Out of memory";
- case error::PARAMOUTOFRANGE: return "Parameter out of range";
- case error::PARAMNOTSPECIFIED: return "Parameter not specified";
- case error::PARAMNOTFOUND: return "Unknown parameter";
- case error::PARAMALREADYSPECIFIED: return "Parameter specified multiple times";
- case error::BADPARAM: return "Invalid parameter";
- case error::SYNTAX: return "Syntax error";
- case error::INTERNAL: return "Internal error";
- }
- return nullptr;
+ return std::find_if(
+ m_ranges.begin(),
+ m_ranges.end(),
+ [&](const auto &r) { return r.min <= value && value <= r.max; });
}
-} // namespace util
+
+} // namespace util \ No newline at end of file
diff --git a/src/lib/util/opresolv.h b/src/lib/util/opresolv.h
index 097d6e303ac..4c059a88d72 100644
--- a/src/lib/util/opresolv.h
+++ b/src/lib/util/opresolv.h
@@ -50,45 +50,79 @@
// TYPE DEFINITIONS
//**************************************************************************
-enum option_type
-{
- OPTIONTYPE_END,
- OPTIONTYPE_INT,
- OPTIONTYPE_STRING,
- OPTIONTYPE_ENUM_BEGIN,
- OPTIONTYPE_ENUM_VALUE
-};
-
-struct option_guide
-{
- enum option_type option_type;
- int parameter;
- const char *identifier;
- const char *display_name;
-};
-
#define OPTION_GUIDE_START(option_guide_) \
- const option_guide option_guide_[] = \
+ const util::option_guide option_guide_ = \
{
#define OPTION_GUIDE_END \
- { OPTIONTYPE_END } \
};
#define OPTION_GUIDE_EXTERN(option_guide_) \
- extern const option_guide option_guide_[]
+ extern const util::option_guide option_guide_
#define OPTION_INT(option_char, identifier, display_name) \
- { OPTIONTYPE_INT, (option_char), (identifier), (display_name) },
+ { util::option_guide::entry::option_type::INT, (option_char), (identifier), (display_name) },
#define OPTION_STRING(option_char, identifier, display_name) \
- { OPTIONTYPE_STRING, (option_char), (identifier), (display_name) },
+ { util::option_guide::entry::option_type::STRING, (option_char), (identifier), (display_name) },
#define OPTION_ENUM_START(option_char, identifier, display_name) \
- { OPTIONTYPE_ENUM_BEGIN, (option_char), (identifier), (display_name) },
+ { util::option_guide::entry::option_type::ENUM_BEGIN, (option_char), (identifier), (display_name) },
#define OPTION_ENUM(value, identifier, display_name) \
- { OPTIONTYPE_ENUM_VALUE, (value), (identifier), (display_name) },
+ { util::option_guide::entry::option_type::ENUM_VALUE, (value), (identifier), (display_name) },
#define OPTION_ENUM_END
namespace util {
+
+// ======================> option_guide
+
+class option_guide
+{
+public:
+ class entry
+ {
+ public:
+ enum class option_type
+ {
+ INT,
+ STRING,
+ ENUM_BEGIN,
+ ENUM_VALUE
+ };
+
+ constexpr entry(option_type type, int parameter = 0, const char *identifier = nullptr, const char *display_name = nullptr)
+ : m_type(type), m_parameter(parameter), m_identifier(identifier), m_display_name(display_name)
+ {
+ }
+
+ // accessors
+ const option_type type() const { return m_type; }
+ int parameter() const { return m_parameter; }
+ const char *identifier() const { return m_identifier; }
+ const char *display_name() const { return m_display_name; }
+
+ private:
+ option_type m_type;
+ int m_parameter;
+ const char *m_identifier;
+ const char *m_display_name;
+ };
+
+ typedef std::vector<option_guide::entry> entrylist;
+
+ option_guide(std::initializer_list<entry> entries)
+ : m_entries(entries)
+ {
+ }
+
+ // methods
+ const entrylist &entries() const { return m_entries; }
+
+private:
+ entrylist m_entries;
+};
+
+// ======================> option_resolution
+
class option_resolution
{
public:
+ // TODO - audit unused parameters
enum class error
{
SUCCESS,
@@ -102,61 +136,98 @@ public:
INTERNAL
};
+ template<typename T>
struct range
{
- int min, max;
+ range() { min = -1; max = -1; }
+ T min, max;
};
- option_resolution(const option_guide *guide, const char *specification);
- ~option_resolution();
-
- // processing options with option_resolution objects
- error add_param(const char *param, const std::string &value);
- error finish();
- int lookup_int(int option_char) const;
- const char *lookup_string(int option_char) const;
+ // class to represent specific entry
+ class entry
+ {
+ friend class option_resolution;
+
+ public:
+ typedef std::vector<range<int> > rangelist;
+
+ // ctor
+ entry(const option_guide::entry &guide_entry);
+
+ // returns true if this entry is subject to range constraints
+ bool is_ranged() const { return !m_ranges.empty(); }
+
+ // accessors
+ bool is_pertinent() const { return m_is_pertinent; }
+ const std::string &value() const;
+ int value_int() const;
+ const std::string &default_value() const { return m_default_value; }
+ const rangelist &ranges() const { return m_ranges; }
+ const option_guide::entrylist::const_iterator enum_value_begin() const { return m_enum_value_begin; }
+ const option_guide::entrylist::const_iterator enum_value_end() const { return m_enum_value_end; }
+
+ // accessors for guide data
+ option_guide::entry::option_type option_type() const { return m_guide_entry.type(); }
+ const char *display_name() const { return m_guide_entry.display_name(); }
+ const char *identifier() const { return m_guide_entry.identifier(); }
+ int parameter() const { return m_guide_entry.parameter(); }
+
+
+ // mutators
+ bool set_value(const std::string &value);
+ bool set_value(int value) { return set_value(numeric_value(value)); }
+
+ // higher level operations
+ bool can_bump_lower() const;
+ bool can_bump_higher() const;
+ bool bump_lower();
+ bool bump_higher();
+
+ private:
+ // references to the option guide
+ const option_guide::entry & m_guide_entry;
+ option_guide::entrylist::const_iterator m_enum_value_begin;
+ option_guide::entrylist::const_iterator m_enum_value_end;
+
+ // runtime state
+ bool m_is_pertinent;
+ std::string m_value;
+ std::string m_default_value;
+ rangelist m_ranges;
+
+ // methods
+ void parse_specification(const char *specification);
+ void set_enum_value_range(option_guide::entrylist::const_iterator begin, option_guide::entrylist::const_iterator end);
+ static std::string numeric_value(int value);
+ rangelist::const_iterator find_in_ranges(int value) const;
+ };
- // accessors
- const char *specification() const { return m_specification; }
- const option_guide *find_option(int option_char) const;
- const option_guide *index_option(int indx) const;
+ // ctor/dtor
+ option_resolution(const option_guide &guide);
+ ~option_resolution();
- // processing option guides
- static size_t count_options(const option_guide *guide, const char *specification);
+ // sets a specification
+ void set_specification(const std::string &specification);
- // processing option specifications
- static error list_ranges(const char *specification, int option_char,
- range *range, size_t range_count);
- static error get_default(const char *specification, int option_char, int *val);
- static error is_valid_value(const char *specification, int option_char, int val);
- static bool contains(const char *specification, int option_char);
+ // entry lookup - note that we're not exposing m_entries directly because we don't really
+ // have a way of making the list be immutable but the members be mutable at the same time
+ std::vector<entry>::iterator entries_begin() { return m_entries.begin(); }
+ std::vector<entry>::iterator entries_end() { return m_entries.end(); }
+ entry *find(int parameter);
+ entry *find(const std::string &identifier);
+ int lookup_int(int parameter);
+ const std::string &lookup_string(int parameter);
// misc
static const char *error_string(error err);
+ static error get_default(const char *specification, int option_char, int *val);
private:
- enum class entry_state
- {
- UNSPECIFIED,
- SPECIFIED
- };
-
- struct entry
- {
- const option_guide *guide_entry;
- entry_state state;
- std::string value;
-
- int int_value() const;
- void set_int_value(int i);
- };
-
- const char *m_specification;
std::vector<entry> m_entries;
- static error resolve_single_param(const char *specification, entry *param_value,
- struct range *range, size_t range_count);
- static const char *lookup_in_specification(const char *specification, const option_guide *option);
+ error set_parameter(std::vector<entry>::iterator iter, const std::string &value);
+
+ static const char *lookup_in_specification(const char *specification, const option_guide::entry &option);
const entry *lookup_entry(int option_char) const;
};
diff --git a/src/mame/machine/psion_pack.cpp b/src/mame/machine/psion_pack.cpp
index d95124372ad..52c0e9b9629 100644
--- a/src/mame/machine/psion_pack.cpp
+++ b/src/mame/machine/psion_pack.cpp
@@ -105,7 +105,7 @@ void datapack_device::device_config_complete()
// option_guide for create new image
//-------------------------------------------------
-const option_guide *datapack_device::create_option_guide() const
+const util::option_guide &datapack_device::create_option_guide() const
{
return datapack_option_guide;
}
diff --git a/src/mame/machine/psion_pack.h b/src/mame/machine/psion_pack.h
index f0358844e93..b5335420f41 100644
--- a/src/mame/machine/psion_pack.h
+++ b/src/mame/machine/psion_pack.h
@@ -40,7 +40,7 @@ public:
virtual bool is_reset_on_load() const override { return 0; }
virtual const char *image_interface() const override { return "psion_pack"; }
virtual const char *file_extensions() const override { return "opk"; }
- virtual const option_guide *create_option_guide() const override;
+ virtual const util::option_guide &create_option_guide() const override;
// specific implementation
UINT8 data_r();
diff --git a/src/tools/imgtool/iflopimg.cpp b/src/tools/imgtool/iflopimg.cpp
index aebd63212f5..f9857fe3db3 100644
--- a/src/tools/imgtool/iflopimg.cpp
+++ b/src/tools/imgtool/iflopimg.cpp
@@ -269,7 +269,7 @@ static void imgtool_floppy_get_info(const imgtool_class *imgclass, UINT32 state,
case IMGTOOLINFO_PTR_OPEN: info->open = imgtool_floppy_open; break;
case IMGTOOLINFO_PTR_CREATE: info->create = imgtool_floppy_create; break;
case IMGTOOLINFO_PTR_CLOSE: info->close = imgtool_floppy_close; break;
- case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = format->param_guidelines ? floppy_option_guide : nullptr; break;
+ case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = format->param_guidelines ? &floppy_option_guide : nullptr; break;
case IMGTOOLINFO_PTR_GET_SECTOR_SIZE: info->get_sector_size = imgtool_floppy_get_sector_size; break;
case IMGTOOLINFO_PTR_READ_SECTOR: info->read_sector = imgtool_floppy_read_sector; break;
case IMGTOOLINFO_PTR_WRITE_SECTOR: info->write_sector = imgtool_floppy_write_sector; break;
diff --git a/src/tools/imgtool/imghd.cpp b/src/tools/imgtool/imghd.cpp
index 79a60a5d010..38f26bfaabb 100644
--- a/src/tools/imgtool/imghd.cpp
+++ b/src/tools/imgtool/imghd.cpp
@@ -247,7 +247,7 @@ void hd_get_info(const imgtool_class *imgclass, UINT32 state, union imgtoolinfo
case IMGTOOLINFO_PTR_CREATE: info->create = mess_hd_image_create; break;
- case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = mess_hd_create_optionguide; break;
+ case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = &mess_hd_create_optionguide; break;
case IMGTOOLINFO_STR_CREATEIMAGE_OPTSPEC: strcpy(info->s = imgtool_temp_str(), mess_hd_create_optionspecs); break;
}
}
diff --git a/src/tools/imgtool/imgtool.cpp b/src/tools/imgtool/imgtool.cpp
index 95efbc9ab18..8039146f22e 100644
--- a/src/tools/imgtool/imgtool.cpp
+++ b/src/tools/imgtool/imgtool.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Nathan Woods
/***************************************************************************
- imgtool.c
+ imgtool.cpp
Core code for Imgtool
@@ -66,7 +66,7 @@ struct imgtool_partition
imgtoolerr_t (*suggest_transfer)(imgtool_partition *partition, const char *path, imgtool_transfer_suggestion *suggestions, size_t suggestions_length);
imgtoolerr_t (*get_chain) (imgtool_partition *partition, const char *path, imgtool_chainent *chain, size_t chain_size);
- const option_guide *writefile_optguide;
+ const util::option_guide *writefile_optguide;
const char *writefile_optspec;
};
@@ -800,7 +800,7 @@ imgtoolerr_t imgtool_partition_open(imgtool_image *image, int partition_index, i
p->get_iconinfo = (imgtoolerr_t (*)(imgtool_partition *, const char *, imgtool_iconinfo *)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_GET_ICON_INFO);
p->suggest_transfer = (imgtoolerr_t (*)(imgtool_partition *, const char *, imgtool_transfer_suggestion *, size_t)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_SUGGEST_TRANSFER);
p->get_chain = (imgtoolerr_t (*)(imgtool_partition *, const char *, imgtool_chainent *, size_t)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_GET_CHAIN);
- p->writefile_optguide = (const option_guide *) imgtool_get_info_ptr(&imgclass, IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE);
+ p->writefile_optguide = (const util::option_guide *) imgtool_get_info_ptr(&imgclass, IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE);
p->writefile_optspec = pool_strdup_allow_null(p->pool, (char*)imgtool_get_info_ptr(&imgclass, IMGTOOLINFO_STR_WRITEFILE_OPTSPEC));
/* mask out if writing is untested */
@@ -928,10 +928,8 @@ void imgtool_partition_get_attribute_name(imgtool_partition *partition, UINT32 a
int imgtool_validitychecks(void)
{
int error = 0;
- int val;
imgtoolerr_t err = (imgtoolerr_t)IMGTOOLERR_SUCCESS;
const imgtool_module *module = nullptr;
- const option_guide *guide_entry;
imgtool_module_features features;
int created_library = FALSE;
@@ -1017,44 +1015,12 @@ int imgtool_validitychecks(void)
if (module->createimage_optguide && module->createimage_optspec)
{
- guide_entry = module->createimage_optguide;
- while (guide_entry->option_type != OPTIONTYPE_END)
- {
- if (util::option_resolution::contains(module->createimage_optspec, guide_entry->parameter))
- {
- switch (guide_entry->option_type)
- {
- case OPTIONTYPE_INT:
- case OPTIONTYPE_ENUM_BEGIN:
- err = (imgtoolerr_t)util::option_resolution::get_default(module->createimage_optspec,
- guide_entry->parameter, &val);
- if (err)
- goto done;
- break;
-
- default:
- break;
- }
- if (!guide_entry->identifier)
- {
- printf("imgtool module %s creation option %d has null identifier\n",
- module->name, (int) (guide_entry - module->createimage_optguide));
- error = 1;
- }
- if (!guide_entry->display_name)
- {
- printf("imgtool module %s creation option %d has null display_name\n",
- module->name, (int) (guide_entry - module->createimage_optguide));
- error = 1;
- }
- }
- guide_entry++;
- }
+ auto resolution = std::make_unique<util::option_resolution>(*module->createimage_optguide);
+ resolution->set_specification(module->createimage_optspec);
}
}
}
-done:
if (created_library)
imgtool_exit();
if (err)
@@ -1218,12 +1184,14 @@ imgtoolerr_t imgtool_image_create(const imgtool_module *module, const char *fnam
/* allocate dummy options if necessary */
if (!opts && module->createimage_optguide)
{
- try { alloc_resolution.reset(new util::option_resolution(module->createimage_optguide, module->createimage_optspec)); }
+ 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);
+
opts = alloc_resolution.get();
}
- if (opts)
- opts->finish();
return internal_open(module, fname, OSD_FOPEN_RW_CREATE, opts, image);
}
@@ -2000,16 +1968,16 @@ imgtoolerr_t imgtool_partition_write_file(imgtool_partition *partition, const ch
/* allocate dummy options if necessary */
if (!opts && partition->writefile_optguide)
{
- try { alloc_resolution.reset(new util::option_resolution(partition->writefile_optguide, partition->writefile_optspec)); }
+ try { alloc_resolution.reset(new util::option_resolution(*partition->writefile_optguide)); }
catch (...)
{
err = IMGTOOLERR_OUTOFMEMORY;
goto done;
}
+ if (partition->writefile_optspec)
+ alloc_resolution->set_specification(partition->writefile_optspec);
opts = alloc_resolution.get();
}
- if (opts)
- opts->finish();
/* if free_space is implemented; do a quick check to see if space is available */
if (partition->free_space)
diff --git a/src/tools/imgtool/library.cpp b/src/tools/imgtool/library.cpp
index 491e1c8e1c8..fd6d6843e45 100644
--- a/src/tools/imgtool/library.cpp
+++ b/src/tools/imgtool/library.cpp
@@ -102,7 +102,7 @@ static void imgtool_library_add_class(imgtool_library *library, const imgtool_cl
module->write_block = (imgtoolerr_t (*)(imgtool_image *, const void *, UINT64)) imgtool_get_info_fct(imgclass, IMGTOOLINFO_PTR_WRITE_BLOCK);
module->list_partitions = (imgtoolerr_t (*)(imgtool_image *, imgtool_partition_info *, size_t)) imgtool_get_info_fct(imgclass, IMGTOOLINFO_PTR_LIST_PARTITIONS);
module->block_size = imgtool_get_info_int(imgclass, IMGTOOLINFO_INT_BLOCK_SIZE);
- module->createimage_optguide = (const option_guide *) imgtool_get_info_ptr(imgclass, IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE);
+ module->createimage_optguide = (const util::option_guide *) imgtool_get_info_ptr(imgclass, IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE);
module->createimage_optspec = imgtool_library_strdup_allow_null(library, (const char*)imgtool_get_info_ptr(imgclass, IMGTOOLINFO_STR_CREATEIMAGE_OPTSPEC));
module->image_extra_bytes += imgtool_get_info_int(imgclass, IMGTOOLINFO_INT_IMAGE_EXTRA_BYTES);
}
diff --git a/src/tools/imgtool/library.h b/src/tools/imgtool/library.h
index 9371f019bfc..63a6a08a5fb 100644
--- a/src/tools/imgtool/library.h
+++ b/src/tools/imgtool/library.h
@@ -291,8 +291,8 @@ union imgtoolinfo
int (*approve_filename_char)(unicode_char ch);
int (*make_class)(int index, imgtool_class *imgclass);
- const option_guide *createimage_optguide;
- const option_guide *writefile_optguide;
+ const util::option_guide *createimage_optguide;
+ const util::option_guide *writefile_optguide;
};
@@ -369,7 +369,7 @@ struct imgtool_module
UINT32 block_size;
- const option_guide *createimage_optguide;
+ const util::option_guide *createimage_optguide;
const char *createimage_optspec;
const void *extra;
diff --git a/src/tools/imgtool/main.cpp b/src/tools/imgtool/main.cpp
index 1faac27ee22..7e30a729619 100644
--- a/src/tools/imgtool/main.cpp
+++ b/src/tools/imgtool/main.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Nathan Woods
/***************************************************************************
- main.c
+ main.cpp
Imgtool command line front end
@@ -17,6 +17,8 @@
#include "imgtool.h"
#include "main.h"
#include "modules.h"
+#include "strformat.h"
+
/* ---------------------------------------------------------------------- */
static void writeusage(FILE *f, int write_word_usage, const struct command *c, char *argv[])
@@ -40,7 +42,6 @@ static int parse_options(int argc, char *argv[], int minunnamed, int maxunnamed,
char *s;
char *name = nullptr;
char *value = nullptr;
- util::option_resolution::error oerr;
static char buf[256];
if (filter)
@@ -97,9 +98,7 @@ static int parse_options(int argc, char *argv[], int minunnamed, int maxunnamed,
if (i < minunnamed)
goto error; /* Too few unnamed */
- oerr = resolution->add_param(name, value);
- if (oerr != util::option_resolution::error::SUCCESS)
- goto opterror;
+ resolution->find(name)->set_value(value);
}
}
}
@@ -113,10 +112,6 @@ optionalreadyspecified:
fprintf(stderr, "Cannot specify multiple %ss\n", name);
return -1;
-opterror:
- fprintf(stderr, "%s: %s\n", name, util::option_resolution::error_string(oerr));
- return -1;
-
error:
fprintf(stderr, "%s: Unrecognized option\n", argv[i]);
return -1;
@@ -328,7 +323,7 @@ static int cmd_put(const struct command *c, int argc, char *argv[])
char **filename_list;
int filename_count;
int partition_index = 0;
- const option_guide *writefile_optguide;
+ const util::option_guide *writefile_optguide;
const char *writefile_optspec;
module = imgtool_find_module(argv[0]);
@@ -353,17 +348,18 @@ static int cmd_put(const struct command *c, int argc, char *argv[])
if (err)
goto done;
- writefile_optguide = (const option_guide *) imgtool_partition_get_info_ptr(partition, IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE);
+ writefile_optguide = (const util::option_guide *) imgtool_partition_get_info_ptr(partition, IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE);
writefile_optspec = (const char *)imgtool_partition_get_info_ptr(partition, IMGTOOLINFO_STR_WRITEFILE_OPTSPEC);
if (writefile_optguide && writefile_optspec)
{
- try { resolution.reset(new util::option_resolution(writefile_optguide, writefile_optspec)); }
+ try { resolution.reset(new util::option_resolution(*writefile_optguide)); }
catch (...)
{
err = IMGTOOLERR_OUTOFMEMORY;
goto done;
}
+ resolution->set_specification(writefile_optspec);
}
}
@@ -592,12 +588,13 @@ static int cmd_create(const struct command *c, int argc, char *argv[])
if (module->createimage_optguide && module->createimage_optspec)
{
- try { resolution.reset(new util::option_resolution(module->createimage_optguide, module->createimage_optspec)); }
+ try { resolution.reset(new util::option_resolution(*module->createimage_optguide)); }
catch (...)
{
err = IMGTOOLERR_OUTOFMEMORY;
goto error;
}
+ resolution->set_specification(module->createimage_optspec);
}
unnamedargs = parse_options(argc, argv, 2, 3, resolution.get(), nullptr, nullptr);
@@ -742,77 +739,64 @@ static int cmd_listfilters(const struct command *c, int argc, char *argv[])
return 0;
}
-static void listoptions(const option_guide *opt_guide, const char *opt_spec)
+static void listoptions(const util::option_guide &opt_guide, const char *opt_spec)
{
- char opt_name[32];
- const char *opt_desc;
- util::option_resolution::range range[32];
- char range_buffer[512];
- char buf[32];
- int i;
-
- assert(opt_guide);
+ util::option_resolution resolution(opt_guide);
+ resolution.set_specification(opt_spec);
fprintf(stdout, "Option Allowed values Description\n");
fprintf(stdout, "---------------- ------------------------------ -----------\n");
- while(opt_guide->option_type != OPTIONTYPE_END)
+
+ for (auto iter = resolution.entries_begin(); iter != resolution.entries_end(); iter++)
{
- range_buffer[0] = 0;
- snprintf(opt_name, ARRAY_LENGTH(opt_name), "--%s", opt_guide->identifier);
- opt_desc = opt_guide->display_name;
+ const auto &entry = *iter;
+ std::stringstream description_buffer;
- /* is this option relevant? */
- if (!strchr(opt_spec, opt_guide->parameter))
- {
- opt_guide++;
- continue;
- }
+ std::string opt_name = string_format("--%s", entry.identifier());
+ const char *opt_desc = entry.display_name();
- switch(opt_guide->option_type) {
- case OPTIONTYPE_INT:
- util::option_resolution::list_ranges(opt_spec, opt_guide->parameter,
- range, ARRAY_LENGTH(range));
+ // is this option relevant?
+ if (!strchr(opt_spec, entry.parameter()))
+ continue;
- for (i = 0; range[i].max >= 0; i++)
+ switch (entry.option_type())
+ {
+ case util::option_guide::entry::option_type::INT:
+ for (const auto &range : entry.ranges())
{
- if (range[i].min == range[i].max)
- snprintf(buf, ARRAY_LENGTH(buf), "%i", range[i].min);
- else
- snprintf(buf, ARRAY_LENGTH(buf), "%i-%i", range[i].min, range[i].max);
+ if (!description_buffer.str().empty())
+ description_buffer << "/";
- if (i > 0)
- strncatz(range_buffer, "/", sizeof(range_buffer));
- strncatz(range_buffer, buf, sizeof(range_buffer));
+ if (range.min == range.max)
+ util::stream_format(description_buffer, "%d", range.min);
+ else
+ util::stream_format(description_buffer, "%d-%d", range.min, range.max);
}
break;
- case OPTIONTYPE_ENUM_BEGIN:
- i = 0;
- while(opt_guide[1].option_type == OPTIONTYPE_ENUM_VALUE)
+ case util::option_guide::entry::option_type::ENUM_BEGIN:
+ for (auto enum_value = entry.enum_value_begin(); enum_value != entry.enum_value_end(); enum_value++)
{
- if (i > 0)
- strncatz(range_buffer, "/", sizeof(range_buffer));
- strncatz(range_buffer, opt_guide[1].identifier, sizeof(range_buffer));
-
- opt_guide++;
- i++;
+ if (!description_buffer.str().empty())
+ description_buffer << "/";
+ description_buffer << enum_value->identifier();
}
break;
- case OPTIONTYPE_STRING:
- snprintf(range_buffer, sizeof(range_buffer), "(string)");
+ case util::option_guide::entry::option_type::STRING:
+ description_buffer << "(string)";
break;
+
default:
assert(0);
break;
}
fprintf(stdout, "%16s %-30s %s\n",
- opt_name,
- range_buffer,
+ opt_name.c_str(),
+ description_buffer.str().c_str(),
opt_desc);
- opt_guide++;
}
}
@@ -821,7 +805,7 @@ static void listoptions(const option_guide *opt_guide, const char *opt_spec)
static int cmd_listdriveroptions(const struct command *c, int argc, char *argv[])
{
const imgtool_module *mod;
- const option_guide *opt_guide;
+ const util::option_guide *opt_guide;
const char *opt_spec;
mod = imgtool_find_module(argv[0]);
@@ -834,12 +818,12 @@ static int cmd_listdriveroptions(const struct command *c, int argc, char *argv[]
fprintf(stdout, "Driver specific options for module '%s':\n\n", argv[0]);
/* list write options */
- opt_guide = (const option_guide *) imgtool_get_info_ptr(&mod->imgclass, IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE);
+ opt_guide = (const util::option_guide *) imgtool_get_info_ptr(&mod->imgclass, IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE);
opt_spec = imgtool_get_info_string(&mod->imgclass, IMGTOOLINFO_STR_WRITEFILE_OPTSPEC);
if (opt_guide)
{
fprintf(stdout, "Image specific file options (usable on the 'put' command):\n\n");
- listoptions(opt_guide, opt_spec);
+ listoptions(*opt_guide, opt_spec);
puts("\n");
}
else
@@ -852,7 +836,7 @@ static int cmd_listdriveroptions(const struct command *c, int argc, char *argv[]
if (opt_guide)
{
fprintf(stdout, "Image specific creation options (usable on the 'create' command):\n\n");
- listoptions(opt_guide, mod->createimage_optspec);
+ listoptions(*opt_guide, mod->createimage_optspec);
puts("\n");
}
else
@@ -940,7 +924,7 @@ int CLIB_DECL main(int argc, char *argv[])
}
/* Usage */
- fprintf(stderr, "imgtool - Generic image manipulation tool for use with MESS\n\n");
+ fprintf(stderr, "imgtool - Generic image manipulation tool for use with MAME\n\n");
for (i = 0; i < ARRAY_LENGTH(cmds); i++)
{
writeusage(stdout, (i == 0), &cmds[i], argv);
diff --git a/src/tools/imgtool/modules/amiga.cpp b/src/tools/imgtool/modules/amiga.cpp
index fa53e24dfad..d85e3698ec9 100644
--- a/src/tools/imgtool/modules/amiga.cpp
+++ b/src/tools/imgtool/modules/amiga.cpp
@@ -2193,7 +2193,7 @@ static imgtoolerr_t amiga_image_writefile(imgtool_partition *partition, const ch
static imgtoolerr_t amiga_image_create(imgtool_image *img, imgtool_stream *stream, util::option_resolution *opts)
{
amiga_floppy *f = (amiga_floppy *) imgtool_image_extra_bytes(img);
- const char *dskname = opts->lookup_string('N');
+ const std::string &dskname = opts->lookup_string('N');
imgtoolerr_t ret;
UINT8 buffer[BSIZE];
root_block root;
@@ -2252,10 +2252,10 @@ static imgtoolerr_t amiga_image_create(imgtool_image *img, imgtool_stream *strea
amiga_setup_time(now, &root.c);
/* volume name */
- if (dskname)
+ if (!dskname.empty())
{
- root.name_len = strlen(dskname);
- memcpy(&root.diskname, dskname, root.name_len);
+ root.name_len = dskname.length();
+ memcpy(&root.diskname, dskname.c_str(), root.name_len);
}
else
{
@@ -2406,6 +2406,6 @@ void amiga_floppy_get_info(const imgtool_class *imgclass, UINT32 state, union im
case IMGTOOLINFO_PTR_SET_ATTRS: info->set_attrs = amiga_image_setattrs; break;
case IMGTOOLINFO_PTR_GET_ICON_INFO: info->get_iconinfo = amiga_image_geticoninfo; break;
case IMGTOOLINFO_PTR_SUGGEST_TRANSFER: info->suggest_transfer = amiga_image_suggesttransfer; break;
- case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = amiga_createimage_optionguide; break;
+ case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = &amiga_createimage_optionguide; break;
}
}
diff --git a/src/tools/imgtool/modules/bml3.cpp b/src/tools/imgtool/modules/bml3.cpp
index c658b42ebf0..f5e88663928 100644
--- a/src/tools/imgtool/modules/bml3.cpp
+++ b/src/tools/imgtool/modules/bml3.cpp
@@ -922,7 +922,7 @@ void bml3_get_info(const imgtool_class *imgclass, UINT32 state, union imgtoolinf
case IMGTOOLINFO_PTR_WRITE_FILE: info->write_file = bml3_diskimage_writefile; break;
case IMGTOOLINFO_PTR_DELETE_FILE: info->delete_file = bml3_diskimage_deletefile; break;
case IMGTOOLINFO_PTR_SUGGEST_TRANSFER: info->suggest_transfer = bml3_diskimage_suggesttransfer; break;
- case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE: info->writefile_optguide = bml3_writefile_optionguide; break;
+ case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE: info->writefile_optguide = &bml3_writefile_optionguide; break;
case IMGTOOLINFO_PTR_FLOPPY_FORMAT: info->p = (void *) floppyoptions_default; break;
}
}
diff --git a/src/tools/imgtool/modules/cybiko.cpp b/src/tools/imgtool/modules/cybiko.cpp
index 649b3e9cab9..a822c904cde 100644
--- a/src/tools/imgtool/modules/cybiko.cpp
+++ b/src/tools/imgtool/modules/cybiko.cpp
@@ -564,7 +564,7 @@ void cybiko_get_info( const imgtool_class *imgclass, UINT32 state, union imgtool
case IMGTOOLINFO_PTR_READ_FILE : info->read_file = cybiko_image_read_file; break;
case IMGTOOLINFO_PTR_WRITE_FILE : info->write_file = cybiko_image_write_file; break;
case IMGTOOLINFO_PTR_DELETE_FILE : info->delete_file = cybiko_image_delete_file; break;
- case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE : info->createimage_optguide = cybiko_image_createimage_optguide; break;
+ case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE : info->createimage_optguide = &cybiko_image_createimage_optguide; break;
// case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE : info->writefile_optguide = cybiko_image_writefile_optguide; break;
// --- the following bits of info are returned as NULL-terminated strings ---
case IMGTOOLINFO_STR_NAME : strcpy( info->s = imgtool_temp_str(), "cybiko"); break;
diff --git a/src/tools/imgtool/modules/hp48.cpp b/src/tools/imgtool/modules/hp48.cpp
index bfc193e9979..46d8674a41a 100644
--- a/src/tools/imgtool/modules/hp48.cpp
+++ b/src/tools/imgtool/modules/hp48.cpp
@@ -726,7 +726,7 @@ void hp48_get_info(const imgtool_class *imgclass, UINT32 state, union imgtoolinf
case IMGTOOLINFO_STR_FILE_EXTENSIONS: strcpy(info->s = imgtool_temp_str(), "crd"); break;
case IMGTOOLINFO_STR_CREATEIMAGE_OPTSPEC: strcpy(info->s = imgtool_temp_str(), hp48_create_optionspec); break;
- case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = hp48_create_optionguide; break;
+ case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = &hp48_create_optionguide; break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case IMGTOOLINFO_PTR_OPEN: info->open = hp48_open; break;
diff --git a/src/tools/imgtool/modules/pc_hard.cpp b/src/tools/imgtool/modules/pc_hard.cpp
index 97ddd3b6894..8244441aa65 100644
--- a/src/tools/imgtool/modules/pc_hard.cpp
+++ b/src/tools/imgtool/modules/pc_hard.cpp
@@ -463,7 +463,7 @@ void pc_chd_get_info(const imgtool_class *imgclass, UINT32 state, union imgtooli
case IMGTOOLINFO_PTR_READ_BLOCK: info->read_block = pc_chd_image_readblock; break;
case IMGTOOLINFO_PTR_WRITE_BLOCK: info->write_block = pc_chd_image_writeblock; break;
case IMGTOOLINFO_PTR_GET_SECTOR_SIZE: info->get_sector_size = pc_chd_image_getsectorsize; break;
- case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = pc_chd_create_optionguide; break;
+ case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = &pc_chd_create_optionguide; break;
case IMGTOOLINFO_PTR_GET_GEOMETRY: info->get_geometry = pc_chd_image_get_geometry; break;
case IMGTOOLINFO_PTR_LIST_PARTITIONS: info->list_partitions = pc_chd_list_partitions; break;
}
diff --git a/src/tools/imgtool/modules/psion.cpp b/src/tools/imgtool/modules/psion.cpp
index 815cd78f265..c0f35f57b2e 100644
--- a/src/tools/imgtool/modules/psion.cpp
+++ b/src/tools/imgtool/modules/psion.cpp
@@ -669,8 +669,8 @@ void psion_get_info( const imgtool_class *imgclass, UINT32 state, union imgtooli
case IMGTOOLINFO_PTR_READ_FILE : info->read_file = datapack_read_file; break;
case IMGTOOLINFO_PTR_WRITE_FILE : info->write_file = datapack_write_file; break;
case IMGTOOLINFO_PTR_DELETE_FILE : info->delete_file = datapack_delete_file; break;
- case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE : info->createimage_optguide = psion_create_optguide; break;
- case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE : info->createimage_optguide = psion_write_optguide; break;
+ case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE : info->createimage_optguide = &psion_create_optguide; break;
+ case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE : info->createimage_optguide = &psion_write_optguide; break;
// --- the following bits of info are returned as NULL-terminated strings ---
case IMGTOOLINFO_STR_NAME : strcpy( info->s = imgtool_temp_str(), "psionpack"); break;
diff --git a/src/tools/imgtool/modules/rsdos.cpp b/src/tools/imgtool/modules/rsdos.cpp
index e067ae8de5f..79ccfd0c6da 100644
--- a/src/tools/imgtool/modules/rsdos.cpp
+++ b/src/tools/imgtool/modules/rsdos.cpp
@@ -617,7 +617,7 @@ void rsdos_get_info(const imgtool_class *imgclass, UINT32 state, union imgtoolin
case IMGTOOLINFO_PTR_WRITE_FILE: info->write_file = rsdos_diskimage_writefile; break;
case IMGTOOLINFO_PTR_DELETE_FILE: info->delete_file = rsdos_diskimage_deletefile; break;
case IMGTOOLINFO_PTR_SUGGEST_TRANSFER: info->suggest_transfer = rsdos_diskimage_suggesttransfer; break;
- case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE: info->writefile_optguide = coco_rsdos_writefile_optionguide; break;
+ case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE: info->writefile_optguide = &coco_rsdos_writefile_optionguide; break;
case IMGTOOLINFO_PTR_FLOPPY_FORMAT: info->p = (void *) floppyoptions_coco; break;
}
}
diff --git a/src/tools/imgtool/modules/thomson.cpp b/src/tools/imgtool/modules/thomson.cpp
index 4d0c6718780..9ae04b0de4e 100644
--- a/src/tools/imgtool/modules/thomson.cpp
+++ b/src/tools/imgtool/modules/thomson.cpp
@@ -1065,7 +1065,7 @@ static imgtoolerr_t thom_write_file(imgtool_partition *part,
}
/* comment */
- char const *const comment = opts->lookup_string('C');
+ char const *const comment = opts->lookup_string('C').c_str();
if (comment && *comment)
strncpy(d.comment, comment, 8);
@@ -1132,7 +1132,7 @@ static imgtoolerr_t thom_create(imgtool_image* img,
/* get parameters */
f->heads = opts->lookup_int('H');
f->tracks = opts->lookup_int('T');
- name = opts->lookup_string('N');
+ name = opts->lookup_string('N').c_str();
switch ( opts->lookup_int('D') ) {
case 0: f->sector_size = 128; f->sectuse_size = 128; break;
case 1: f->sector_size = 256; f->sectuse_size = 255; break;
@@ -1571,7 +1571,7 @@ static void thom_basic_get_info(const imgtool_class *clas,
case IMGTOOLINFO_PTR_CREATE:
info->create = thom_create; break;
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE:
- info->createimage_optguide = thom_createimage_optguide; break;
+ info->createimage_optguide = &thom_createimage_optguide; break;
case IMGTOOLINFO_PTR_BEGIN_ENUM:
info->begin_enum = thom_begin_enum; break;
case IMGTOOLINFO_PTR_NEXT_ENUM:
@@ -1581,7 +1581,7 @@ static void thom_basic_get_info(const imgtool_class *clas,
case IMGTOOLINFO_PTR_WRITE_FILE:
info->write_file = thom_write_file; break;
case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE:
- info->writefile_optguide = thom_writefile_optguide; break;
+ info->writefile_optguide = &thom_writefile_optguide; break;
case IMGTOOLINFO_STR_WRITEFILE_OPTSPEC:
strcpy( info->s = imgtool_temp_str(), "T[0]-4;F[0]-2;C" ); break;
case IMGTOOLINFO_PTR_SUGGEST_TRANSFER:
diff --git a/src/tools/imgtool/modules/ti99.cpp b/src/tools/imgtool/modules/ti99.cpp
index 5e643af8129..d1d18eb1acc 100644
--- a/src/tools/imgtool/modules/ti99.cpp
+++ b/src/tools/imgtool/modules/ti99.cpp
@@ -3929,7 +3929,7 @@ void ti99_old_get_info(const imgtool_class *imgclass, UINT32 state, union imgtoo
case IMGTOOLINFO_STR_DESCRIPTION: strcpy(info->s = imgtool_temp_str(), "TI99 Diskette (old MESS format)"); break;
case IMGTOOLINFO_PTR_OPEN: info->open = dsk_image_init_mess; break;
case IMGTOOLINFO_PTR_CREATE: info->create = dsk_image_create_mess; break;
- case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = dsk_create_optionguide; break;
+ case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = &dsk_create_optionguide; break;
case IMGTOOLINFO_STR_CREATEIMAGE_OPTSPEC: strcpy(info->s = imgtool_temp_str(), dsk_create_optionspecs); break;
default: ti99_dsk_getinfo(imgclass, state, info); break;
}
@@ -3943,7 +3943,7 @@ void ti99_v9t9_get_info(const imgtool_class *imgclass, UINT32 state, union imgto
case IMGTOOLINFO_STR_DESCRIPTION: strcpy(info->s = imgtool_temp_str(), "TI99 Diskette (V9T9 format)"); break;
case IMGTOOLINFO_PTR_OPEN: info->open = dsk_image_init_v9t9; break;
case IMGTOOLINFO_PTR_CREATE: info->create = dsk_image_create_v9t9; break;
- case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = dsk_create_optionguide; break;
+ case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = &dsk_create_optionguide; break;
case IMGTOOLINFO_STR_CREATEIMAGE_OPTSPEC: strcpy(info->s = imgtool_temp_str(), dsk_create_optionspecs); break;
default: ti99_dsk_getinfo(imgclass, state, info); break;
}
@@ -5244,7 +5244,7 @@ static imgtoolerr_t dsk_image_create(imgtool_image *image, imgtool_stream *f, ut
l1_img.file_handle = f;
/* read options */
- volname = createoptions->lookup_string(dsk_createopts_volname);
+ volname = createoptions->lookup_string(dsk_createopts_volname).c_str();
l1_img.geometry.heads = createoptions->lookup_int(dsk_createopts_sides);
l1_img.geometry.cylinders = createoptions->lookup_int(dsk_createopts_tracks);
l1_img.geometry.secspertrack = createoptions->lookup_int(dsk_createopts_sectors);
diff --git a/src/tools/imgtool/modules/ti990hd.cpp b/src/tools/imgtool/modules/ti990hd.cpp
index d4731f4d753..07987802cc5 100644
--- a/src/tools/imgtool/modules/ti990hd.cpp
+++ b/src/tools/imgtool/modules/ti990hd.cpp
@@ -442,7 +442,7 @@ void ti990_get_info(const imgtool_class *imgclass, UINT32 state, union imgtoolin
case IMGTOOLINFO_PTR_DELETE_FILE: /* info->delete_file = ti990_image_deletefile; */ break;
case IMGTOOLINFO_PTR_CREATE: info->create = ti990_image_create; break;
- case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = ti990_create_optionguide; break;
+ case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = &ti990_create_optionguide; break;
case IMGTOOLINFO_STR_CREATEIMAGE_OPTSPEC: strcpy(info->s = imgtool_temp_str(), ti990_create_optionspecs); break;
}
}
diff --git a/src/tools/imgtool/modules/vzdos.cpp b/src/tools/imgtool/modules/vzdos.cpp
index 09f01556b06..7d06ffc552c 100644
--- a/src/tools/imgtool/modules/vzdos.cpp
+++ b/src/tools/imgtool/modules/vzdos.cpp
@@ -953,7 +953,7 @@ void vzdos_get_info(const imgtool_class *imgclass, UINT32 state, union imgtoolin
case IMGTOOLINFO_PTR_WRITE_FILE: info->write_file = vzdos_diskimage_writefile; break;
case IMGTOOLINFO_PTR_DELETE_FILE: info->delete_file = vzdos_diskimage_deletefile; break;
case IMGTOOLINFO_PTR_FLOPPY_CREATE: info->create = vzdos_diskimage_create; break;
- case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE: info->writefile_optguide = vzdos_writefile_optionguide; break;
+ case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE: info->writefile_optguide = &vzdos_writefile_optionguide; break;
case IMGTOOLINFO_PTR_SUGGEST_TRANSFER: info->suggest_transfer = vzdos_diskimage_suggesttransfer; break;
case IMGTOOLINFO_PTR_FLOPPY_FORMAT: info->p = (void *) floppyoptions_vz; break;
}