mirror of
https://github.com/holub/mame
synced 2025-07-09 19:57:45 +03:00
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
This commit is contained in:
parent
89737886e0
commit
b60879e595
@ -62,7 +62,7 @@ void diablo_image_device::device_config_complete()
|
|||||||
update_names();
|
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;
|
return dsk_option_guide;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ public:
|
|||||||
virtual bool is_reset_on_load() const override { return 0; }
|
virtual bool is_reset_on_load() const override { return 0; }
|
||||||
virtual const char *image_interface() const override { return m_interface; }
|
virtual const char *image_interface() const override { return m_interface; }
|
||||||
virtual const char *file_extensions() const override { return "chd,dsk"; }
|
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
|
// specific implementation
|
||||||
hard_disk_file *get_hard_disk_file() { return m_hard_disk_handle; }
|
hard_disk_file *get_hard_disk_file() { return m_hard_disk_handle; }
|
||||||
|
@ -114,7 +114,7 @@ public:
|
|||||||
virtual bool is_reset_on_load() const override { return 0; }
|
virtual bool is_reset_on_load() const override { return 0; }
|
||||||
virtual const char *image_interface() const override;
|
virtual const char *image_interface() const override;
|
||||||
virtual const char *file_extensions() const override { return m_extension_list; }
|
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();
|
floppy_image_legacy *flopimg_get_image();
|
||||||
void floppy_drive_set_geometry(floppy_type_t type);
|
void floppy_drive_set_geometry(floppy_type_t type);
|
||||||
|
@ -85,7 +85,7 @@ void harddisk_image_device::device_config_complete()
|
|||||||
update_names();
|
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;
|
return hd_option_guide;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ public:
|
|||||||
virtual bool is_reset_on_load() const override { return 0; }
|
virtual bool is_reset_on_load() const override { return 0; }
|
||||||
virtual const char *image_interface() const override { return m_interface; }
|
virtual const char *image_interface() const override { return m_interface; }
|
||||||
virtual const char *file_extensions() const override { return "chd,hd"; }
|
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
|
// specific implementation
|
||||||
hard_disk_file *get_hard_disk_file() { return m_hard_disk_handle; }
|
hard_disk_file *get_hard_disk_file() { return m_hard_disk_handle; }
|
||||||
|
@ -1223,6 +1223,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
|
// update_names - update brief and instance names
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
@ -160,11 +160,11 @@ public:
|
|||||||
virtual bool is_reset_on_load() const = 0;
|
virtual bool is_reset_on_load() const = 0;
|
||||||
virtual const char *image_interface() const { return nullptr; }
|
virtual const char *image_interface() const { return nullptr; }
|
||||||
virtual const char *file_extensions() const = 0;
|
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_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 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();
|
const char *error();
|
||||||
void seterror(image_error_t err, const char *message);
|
void seterror(image_error_t err, const char *message);
|
||||||
|
@ -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)
|
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;
|
floppy_image_legacy *floppy = nullptr;
|
||||||
util::option_resolution::error oerr;
|
|
||||||
floperr_t err;
|
floperr_t err;
|
||||||
int heads, tracks, h, t;
|
int heads, tracks, h, t;
|
||||||
std::unique_ptr<util::option_resolution> alloc_resolution;
|
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 this format expects creation parameters and none were specified, create some */
|
||||||
if (!parameters && format->param_guidelines)
|
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)
|
if (!alloc_resolution)
|
||||||
{
|
{
|
||||||
err = FLOPPY_ERROR_OUTOFMEMORY;
|
err = FLOPPY_ERROR_OUTOFMEMORY;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
alloc_resolution->set_specification(format->param_guidelines);
|
||||||
parameters = alloc_resolution.get();
|
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 */
|
/* call the format constructor */
|
||||||
err = format->construct(floppy, format, parameters);
|
err = format->construct(floppy, format, parameters);
|
||||||
if (err)
|
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 */
|
/* create a dummy resolution; if no parameters were specified */
|
||||||
if (!parameters)
|
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)
|
if (!alloc_resolution)
|
||||||
return FLOPPY_ERROR_OUTOFMEMORY;
|
return FLOPPY_ERROR_OUTOFMEMORY;
|
||||||
|
alloc_resolution->set_specification(floppy->floppy_option->param_guidelines);
|
||||||
|
|
||||||
parameters = alloc_resolution.get();
|
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);
|
err = format->format_track(floppy, head, track, parameters);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// copyright-holders:Nathan Woods
|
// copyright-holders:Nathan Woods
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|
||||||
opresolv.h
|
opresolv.cpp
|
||||||
|
|
||||||
Extensible ranged option resolution handling
|
Extensible ranged option resolution handling
|
||||||
|
|
||||||
@ -19,226 +19,51 @@
|
|||||||
|
|
||||||
|
|
||||||
namespace util {
|
namespace util {
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
option_resolution
|
option_resolution
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
// entry::int_value
|
// ctor
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
int option_resolution::entry::int_value() const
|
option_resolution::option_resolution(const option_guide &guide)
|
||||||
{
|
{
|
||||||
return atoi(value.c_str());
|
// reserve space for entries
|
||||||
}
|
m_entries.reserve(guide.entries().size());
|
||||||
|
|
||||||
|
// initialize each of the entries; can't use foreach because we need to scan the
|
||||||
// -------------------------------------------------
|
// ENUM_VALUE entries
|
||||||
// entry::set_int_value
|
for (auto iter = guide.entries().cbegin(); iter != guide.entries().cend(); iter++)
|
||||||
// -------------------------------------------------
|
|
||||||
|
|
||||||
void option_resolution::entry::set_int_value(int i)
|
|
||||||
{
|
|
||||||
value = string_format("%d", i);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
|
||||||
// resolve_single_param
|
|
||||||
// -------------------------------------------------
|
|
||||||
|
|
||||||
option_resolution::error option_resolution::resolve_single_param(const char *specification, option_resolution::entry *param_value,
|
|
||||||
struct range *range, size_t range_count)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
while(*s && !isalpha(*s))
|
|
||||||
{
|
{
|
||||||
if (*s == '-')
|
// create the entry
|
||||||
{
|
m_entries.emplace_back(*iter);
|
||||||
/* range specifier */
|
entry &entry(m_entries.back());
|
||||||
if (flags & (FLAG_IN_RANGE|FLAG_IN_DEFAULT))
|
|
||||||
{
|
|
||||||
return error::SYNTAX;
|
|
||||||
}
|
|
||||||
flags |= FLAG_IN_RANGE;
|
|
||||||
s++;
|
|
||||||
|
|
||||||
if (range)
|
// if this is an enumeration, identify the values
|
||||||
{
|
if (iter->type() == option_guide::entry::option_type::ENUM_BEGIN)
|
||||||
range->max = -1;
|
|
||||||
if ((flags & FLAG_HALF_RANGE) == 0)
|
|
||||||
{
|
|
||||||
range->min = -1;
|
|
||||||
flags |= FLAG_HALF_RANGE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (*s == '[')
|
|
||||||
{
|
{
|
||||||
/* begin default value */
|
// enum values begin after the ENUM_BEGIN
|
||||||
if (flags & (FLAG_IN_DEFAULT|FLAG_DEFAULT_SPECIFIED))
|
auto enum_value_begin = iter + 1;
|
||||||
{
|
auto enum_value_end = enum_value_begin;
|
||||||
return error::SYNTAX;
|
|
||||||
}
|
|
||||||
flags |= FLAG_IN_DEFAULT;
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
else if (*s == ']')
|
|
||||||
{
|
|
||||||
/* end default value */
|
|
||||||
if ((flags & FLAG_IN_DEFAULT) == 0)
|
|
||||||
{
|
|
||||||
return error::SYNTAX;
|
|
||||||
}
|
|
||||||
flags &= ~FLAG_IN_DEFAULT;
|
|
||||||
flags |= FLAG_DEFAULT_SPECIFIED;
|
|
||||||
s++;
|
|
||||||
|
|
||||||
if (param_value && param_value->int_value() == -1)
|
// and identify all entries of type ENUM_VALUE
|
||||||
param_value->set_int_value(value);
|
while (enum_value_end != guide.entries().end() && enum_value_end->type() == option_guide::entry::option_type::ENUM_VALUE)
|
||||||
}
|
|
||||||
else if (*s == '/')
|
|
||||||
{
|
|
||||||
/* value separator */
|
|
||||||
if (flags & (FLAG_IN_DEFAULT|FLAG_IN_RANGE))
|
|
||||||
{
|
{
|
||||||
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
|
// set the range
|
||||||
if (param_value && (param_value->int_value() != -1) && (param_value->int_value() != value))
|
entry.set_enum_value_range(enum_value_begin, enum_value_end);
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we can't have zero length guidelines strings
|
|
||||||
if (s == specification)
|
|
||||||
{
|
|
||||||
return error::SYNTAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
return error::SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
// lookup_in_specification
|
// dtor
|
||||||
// -------------------------------------------------
|
|
||||||
|
|
||||||
const char *option_resolution::lookup_in_specification(const char *specification, const option_guide *option)
|
|
||||||
{
|
|
||||||
const char *s;
|
|
||||||
s = strchr(specification, option->parameter);
|
|
||||||
return s ? s + 1 : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
|
||||||
// ctor
|
|
||||||
// -------------------------------------------------
|
|
||||||
|
|
||||||
option_resolution::option_resolution(const option_guide *guide, const char *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);
|
|
||||||
|
|
||||||
// set up the entries list
|
|
||||||
m_specification = specification;
|
|
||||||
m_entries.resize(option_count);
|
|
||||||
|
|
||||||
// initialize each of the entries
|
|
||||||
opt = 0;
|
|
||||||
guide_entry = guide;
|
|
||||||
while(guide_entry->option_type != OPTIONTYPE_END)
|
|
||||||
{
|
|
||||||
switch(guide_entry->option_type)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
guide_entry++;
|
|
||||||
}
|
|
||||||
assert(opt == option_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
|
||||||
// dtor
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
option_resolution::~option_resolution()
|
option_resolution::~option_resolution()
|
||||||
@ -247,318 +72,412 @@ option_resolution::~option_resolution()
|
|||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
// add_param
|
// lookup_in_specification
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
option_resolution::error option_resolution::add_param(const char *param, const std::string &value)
|
const char *option_resolution::lookup_in_specification(const char *specification, const option_guide::entry &option)
|
||||||
{
|
{
|
||||||
int i;
|
const char *s;
|
||||||
bool must_resolve;
|
s = strchr(specification, option.parameter());
|
||||||
error err;
|
return s ? s + 1 : nullptr;
|
||||||
const char *option_specification;
|
|
||||||
entry *entry = 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;
|
|
||||||
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
return error::INTERNAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
// finish
|
// set_specification - sets the option specification
|
||||||
|
// and mutates values accordingly
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
option_resolution::error option_resolution::finish()
|
void option_resolution::set_specification(const std::string &specification)
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
|
||||||
// lookup_entry
|
|
||||||
// -------------------------------------------------
|
|
||||||
|
|
||||||
const option_resolution::entry *option_resolution::lookup_entry(int option_char) const
|
|
||||||
{
|
{
|
||||||
for (auto &entry : m_entries)
|
for (auto &entry : m_entries)
|
||||||
{
|
{
|
||||||
switch(entry.guide_entry->option_type) {
|
// find this entry's info in the specification
|
||||||
case OPTIONTYPE_INT:
|
auto entry_specification = lookup_in_specification(specification.c_str(), entry.m_guide_entry);
|
||||||
case OPTIONTYPE_STRING:
|
|
||||||
case OPTIONTYPE_ENUM_BEGIN:
|
|
||||||
if (entry.guide_entry->parameter == option_char)
|
|
||||||
return &entry;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
// parse this entry's specification (e.g. - set up ranges and defaults)
|
||||||
assert(FALSE);
|
entry.parse_specification(entry_specification);
|
||||||
return nullptr;
|
|
||||||
|
// is this a range typed that needs to be defaulted for the first time?
|
||||||
|
if (entry.is_pertinent() && entry.is_ranged() && entry.value().empty())
|
||||||
|
{
|
||||||
|
entry.set_value(entry.default_value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
// lookup_int
|
// find
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
int option_resolution::lookup_int(int option_char) const
|
option_resolution::entry *option_resolution::find(int parameter)
|
||||||
{
|
{
|
||||||
auto entry = lookup_entry(option_char);
|
auto iter = std::find_if(
|
||||||
return entry ? entry->int_value() : -1;
|
m_entries.begin(),
|
||||||
|
m_entries.end(),
|
||||||
|
[&](const entry &e) { return e.parameter() == parameter; });
|
||||||
|
|
||||||
|
return iter != m_entries.end()
|
||||||
|
? &*iter
|
||||||
|
: nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
// lookup_string
|
// find
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
const char *option_resolution::lookup_string(int option_char) const
|
option_resolution::entry *option_resolution::find(const std::string &identifier)
|
||||||
{
|
{
|
||||||
auto entry = lookup_entry(option_char);
|
auto iter = std::find_if(
|
||||||
return entry ? entry->value.c_str() : nullptr;
|
m_entries.begin(),
|
||||||
|
m_entries.end(),
|
||||||
|
[&](const entry &e) { return !strcmp(e.identifier(), identifier.c_str()); });
|
||||||
|
|
||||||
|
return iter != m_entries.end()
|
||||||
|
? &*iter
|
||||||
|
: nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
// find_option
|
// lookup_int
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
const option_guide *option_resolution::find_option(int option_char) const
|
int option_resolution::lookup_int(int parameter)
|
||||||
{
|
{
|
||||||
auto entry = lookup_entry(option_char);
|
auto entry = find(parameter);
|
||||||
return entry ? entry->guide_entry : nullptr;
|
assert(entry != nullptr);
|
||||||
|
return entry->value_int();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
// index_option
|
// lookup_string
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
const option_guide *option_resolution::index_option(int indx) const
|
const std::string &option_resolution::lookup_string(int parameter)
|
||||||
{
|
{
|
||||||
if ((indx < 0) || (indx >= m_entries.size()))
|
auto entry = find(parameter);
|
||||||
return nullptr;
|
assert(entry != nullptr);
|
||||||
return m_entries[indx].guide_entry;
|
return entry->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
// count_options
|
// error_string
|
||||||
// -------------------------------------------------
|
|
||||||
|
|
||||||
size_t option_resolution::count_options(const option_guide *guide, const char *specification)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
|
||||||
// list_ranges
|
|
||||||
// -------------------------------------------------
|
|
||||||
|
|
||||||
option_resolution::error option_resolution::list_ranges(const char *specification, int option_char, range *range, size_t range_count)
|
|
||||||
{
|
|
||||||
assert(range_count > 0);
|
|
||||||
|
|
||||||
// clear out range
|
|
||||||
memset(range, -1, sizeof(*range) * range_count);
|
|
||||||
range_count--;
|
|
||||||
|
|
||||||
specification = strchr(specification, option_char);
|
|
||||||
if (!specification)
|
|
||||||
{
|
|
||||||
return error::SYNTAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolve_single_param(specification + 1, nullptr, range, range_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
|
||||||
// get_default
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
option_resolution::error option_resolution::get_default(const char *specification, int option_char, int *val)
|
option_resolution::error option_resolution::get_default(const char *specification, int option_char, int *val)
|
||||||
{
|
{
|
||||||
assert(val);
|
// NYI
|
||||||
|
return error::INTERNAL;
|
||||||
// clear out default
|
|
||||||
*val = -1;
|
|
||||||
|
|
||||||
specification = strchr(specification, option_char);
|
|
||||||
if (!specification)
|
|
||||||
{
|
|
||||||
return error::SYNTAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
entry ent;
|
|
||||||
auto err = resolve_single_param(specification + 1, &ent, nullptr, 0);
|
|
||||||
*val = ent.int_value();
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
// list_ranges
|
// error_string
|
||||||
// -------------------------------------------------
|
|
||||||
|
|
||||||
option_resolution::error option_resolution::is_valid_value(const char *specification, int option_char, int val)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
for (i = 0; (ranges[i].min >= 0) && (ranges[i].max >= 0); i++)
|
|
||||||
{
|
|
||||||
if ((ranges[i].min <= val) && (ranges[i].max >= val))
|
|
||||||
return error::SUCCESS;
|
|
||||||
}
|
|
||||||
return error::PARAMOUTOFRANGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
|
||||||
// contains
|
|
||||||
// -------------------------------------------------
|
|
||||||
|
|
||||||
bool option_resolution::contains(const char *specification, int option_char)
|
|
||||||
{
|
|
||||||
return strchr(specification, option_char) != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
|
||||||
// error_string
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
const char *option_resolution::error_string(option_resolution::error err)
|
const char *option_resolution::error_string(option_resolution::error err)
|
||||||
{
|
{
|
||||||
switch (err)
|
switch (err)
|
||||||
{
|
{
|
||||||
case error::SUCCESS: return "The operation completed successfully";
|
case error::SUCCESS: return "The operation completed successfully";
|
||||||
case error::OUTOFMEMORY: return "Out of memory";
|
case error::OUTOFMEMORY: return "Out of memory";
|
||||||
case error::PARAMOUTOFRANGE: return "Parameter out of range";
|
case error::PARAMOUTOFRANGE: return "Parameter out of range";
|
||||||
case error::PARAMNOTSPECIFIED: return "Parameter not specified";
|
case error::PARAMNOTSPECIFIED: return "Parameter not specified";
|
||||||
case error::PARAMNOTFOUND: return "Unknown parameter";
|
case error::PARAMNOTFOUND: return "Unknown parameter";
|
||||||
case error::PARAMALREADYSPECIFIED: return "Parameter specified multiple times";
|
case error::PARAMALREADYSPECIFIED: return "Parameter specified multiple times";
|
||||||
case error::BADPARAM: return "Invalid parameter";
|
case error::BADPARAM: return "Invalid parameter";
|
||||||
case error::SYNTAX: return "Syntax error";
|
case error::SYNTAX: return "Syntax error";
|
||||||
case error::INTERNAL: return "Internal error";
|
case error::INTERNAL: return "Internal error";
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace util
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// entry::ctor
|
||||||
|
// -------------------------------------------------
|
||||||
|
|
||||||
|
option_resolution::entry::entry(const option_guide::entry &guide_entry)
|
||||||
|
: m_guide_entry(guide_entry), m_is_pertinent(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// entry::set_enum_value_range
|
||||||
|
// -------------------------------------------------
|
||||||
|
|
||||||
|
void option_resolution::entry::set_enum_value_range(option_guide::entrylist::const_iterator begin, option_guide::entrylist::const_iterator end)
|
||||||
|
{
|
||||||
|
m_enum_value_begin = begin;
|
||||||
|
m_enum_value_end = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// entry::parse_specification
|
||||||
|
// -------------------------------------------------
|
||||||
|
|
||||||
|
void option_resolution::entry::parse_specification(const char *specification)
|
||||||
|
{
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// entry::numeric_value
|
||||||
|
// -------------------------------------------------
|
||||||
|
|
||||||
|
std::string option_resolution::entry::numeric_value(int value)
|
||||||
|
{
|
||||||
|
return string_format("%d", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// entry::value
|
||||||
|
// -------------------------------------------------
|
||||||
|
|
||||||
|
const std::string &option_resolution::entry::value() const
|
||||||
|
{
|
||||||
|
static std::string empty_string;
|
||||||
|
return is_pertinent() ? m_value : empty_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// entry::value_int
|
||||||
|
// -------------------------------------------------
|
||||||
|
|
||||||
|
int option_resolution::entry::value_int() const
|
||||||
|
{
|
||||||
|
return is_pertinent() ? atoi(m_value.c_str()) : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// looks good! change the value
|
||||||
|
m_value = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// entry::can_bump_lower
|
||||||
|
// -------------------------------------------------
|
||||||
|
|
||||||
|
bool option_resolution::entry::can_bump_lower() const
|
||||||
|
{
|
||||||
|
return !m_ranges.empty()
|
||||||
|
&& value_int() > m_ranges.front().min;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// entry::can_bump_higher
|
||||||
|
// -------------------------------------------------
|
||||||
|
|
||||||
|
bool option_resolution::entry::can_bump_higher() const
|
||||||
|
{
|
||||||
|
return !m_ranges.empty()
|
||||||
|
&& value_int() < m_ranges.back().max;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// entry::bump_lower
|
||||||
|
// -------------------------------------------------
|
||||||
|
|
||||||
|
bool option_resolution::entry::bump_lower()
|
||||||
|
{
|
||||||
|
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->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
|
||||||
|
{
|
||||||
|
// at the minimum; don't bump
|
||||||
|
new_value = old_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_value(new_value);
|
||||||
|
return new_value != old_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// entry::bump_higher
|
||||||
|
// -------------------------------------------------
|
||||||
|
|
||||||
|
bool option_resolution::entry::bump_higher()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// entry::find_in_ranges
|
||||||
|
// -------------------------------------------------
|
||||||
|
|
||||||
|
option_resolution::entry::rangelist::const_iterator option_resolution::entry::find_in_ranges(int value) const
|
||||||
|
{
|
||||||
|
return std::find_if(
|
||||||
|
m_ranges.begin(),
|
||||||
|
m_ranges.end(),
|
||||||
|
[&](const auto &r) { return r.min <= value && value <= r.max; });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace util
|
@ -50,45 +50,79 @@
|
|||||||
// TYPE DEFINITIONS
|
// 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_) \
|
#define OPTION_GUIDE_START(option_guide_) \
|
||||||
const option_guide option_guide_[] = \
|
const util::option_guide option_guide_ = \
|
||||||
{
|
{
|
||||||
#define OPTION_GUIDE_END \
|
#define OPTION_GUIDE_END \
|
||||||
{ OPTIONTYPE_END } \
|
|
||||||
};
|
};
|
||||||
#define OPTION_GUIDE_EXTERN(option_guide_) \
|
#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) \
|
#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) \
|
#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) \
|
#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) \
|
#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
|
#define OPTION_ENUM_END
|
||||||
|
|
||||||
namespace util {
|
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
|
class option_resolution
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// TODO - audit unused parameters
|
||||||
enum class error
|
enum class error
|
||||||
{
|
{
|
||||||
SUCCESS,
|
SUCCESS,
|
||||||
@ -102,61 +136,98 @@ public:
|
|||||||
INTERNAL
|
INTERNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
struct range
|
struct range
|
||||||
{
|
{
|
||||||
int min, max;
|
range() { min = -1; max = -1; }
|
||||||
|
T min, max;
|
||||||
};
|
};
|
||||||
|
|
||||||
option_resolution(const option_guide *guide, const char *specification);
|
// 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ctor/dtor
|
||||||
|
option_resolution(const option_guide &guide);
|
||||||
~option_resolution();
|
~option_resolution();
|
||||||
|
|
||||||
// processing options with option_resolution objects
|
// sets a specification
|
||||||
error add_param(const char *param, const std::string &value);
|
void set_specification(const std::string &specification);
|
||||||
error finish();
|
|
||||||
int lookup_int(int option_char) const;
|
|
||||||
const char *lookup_string(int option_char) const;
|
|
||||||
|
|
||||||
// accessors
|
// entry lookup - note that we're not exposing m_entries directly because we don't really
|
||||||
const char *specification() const { return m_specification; }
|
// have a way of making the list be immutable but the members be mutable at the same time
|
||||||
const option_guide *find_option(int option_char) const;
|
std::vector<entry>::iterator entries_begin() { return m_entries.begin(); }
|
||||||
const option_guide *index_option(int indx) const;
|
std::vector<entry>::iterator entries_end() { return m_entries.end(); }
|
||||||
|
entry *find(int parameter);
|
||||||
// processing option guides
|
entry *find(const std::string &identifier);
|
||||||
static size_t count_options(const option_guide *guide, const char *specification);
|
int lookup_int(int parameter);
|
||||||
|
const std::string &lookup_string(int parameter);
|
||||||
// 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);
|
|
||||||
|
|
||||||
// misc
|
// misc
|
||||||
static const char *error_string(error err);
|
static const char *error_string(error err);
|
||||||
|
static error get_default(const char *specification, int option_char, int *val);
|
||||||
|
|
||||||
private:
|
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;
|
std::vector<entry> m_entries;
|
||||||
|
|
||||||
static error resolve_single_param(const char *specification, entry *param_value,
|
error set_parameter(std::vector<entry>::iterator iter, const std::string &value);
|
||||||
struct range *range, size_t range_count);
|
|
||||||
static const char *lookup_in_specification(const char *specification, const option_guide *option);
|
static const char *lookup_in_specification(const char *specification, const option_guide::entry &option);
|
||||||
const entry *lookup_entry(int option_char) const;
|
const entry *lookup_entry(int option_char) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ void datapack_device::device_config_complete()
|
|||||||
// option_guide for create new image
|
// 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;
|
return datapack_option_guide;
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ public:
|
|||||||
virtual bool is_reset_on_load() const override { return 0; }
|
virtual bool is_reset_on_load() const override { return 0; }
|
||||||
virtual const char *image_interface() const override { return "psion_pack"; }
|
virtual const char *image_interface() const override { return "psion_pack"; }
|
||||||
virtual const char *file_extensions() const override { return "opk"; }
|
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
|
// specific implementation
|
||||||
UINT8 data_r();
|
UINT8 data_r();
|
||||||
|
@ -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_OPEN: info->open = imgtool_floppy_open; break;
|
||||||
case IMGTOOLINFO_PTR_CREATE: info->create = imgtool_floppy_create; break;
|
case IMGTOOLINFO_PTR_CREATE: info->create = imgtool_floppy_create; break;
|
||||||
case IMGTOOLINFO_PTR_CLOSE: info->close = imgtool_floppy_close; 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_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_READ_SECTOR: info->read_sector = imgtool_floppy_read_sector; break;
|
||||||
case IMGTOOLINFO_PTR_WRITE_SECTOR: info->write_sector = imgtool_floppy_write_sector; break;
|
case IMGTOOLINFO_PTR_WRITE_SECTOR: info->write_sector = imgtool_floppy_write_sector; break;
|
||||||
|
@ -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_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;
|
case IMGTOOLINFO_STR_CREATEIMAGE_OPTSPEC: strcpy(info->s = imgtool_temp_str(), mess_hd_create_optionspecs); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// copyright-holders:Nathan Woods
|
// copyright-holders:Nathan Woods
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
|
|
||||||
imgtool.c
|
imgtool.cpp
|
||||||
|
|
||||||
Core code for Imgtool
|
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 (*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);
|
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;
|
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->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->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->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));
|
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 */
|
/* 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 imgtool_validitychecks(void)
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int val;
|
|
||||||
imgtoolerr_t err = (imgtoolerr_t)IMGTOOLERR_SUCCESS;
|
imgtoolerr_t err = (imgtoolerr_t)IMGTOOLERR_SUCCESS;
|
||||||
const imgtool_module *module = nullptr;
|
const imgtool_module *module = nullptr;
|
||||||
const option_guide *guide_entry;
|
|
||||||
imgtool_module_features features;
|
imgtool_module_features features;
|
||||||
int created_library = FALSE;
|
int created_library = FALSE;
|
||||||
|
|
||||||
@ -1017,44 +1015,12 @@ int imgtool_validitychecks(void)
|
|||||||
|
|
||||||
if (module->createimage_optguide && module->createimage_optspec)
|
if (module->createimage_optguide && module->createimage_optspec)
|
||||||
{
|
{
|
||||||
guide_entry = module->createimage_optguide;
|
auto resolution = std::make_unique<util::option_resolution>(*module->createimage_optguide);
|
||||||
while (guide_entry->option_type != OPTIONTYPE_END)
|
resolution->set_specification(module->createimage_optspec);
|
||||||
{
|
|
||||||
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++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
|
||||||
if (created_library)
|
if (created_library)
|
||||||
imgtool_exit();
|
imgtool_exit();
|
||||||
if (err)
|
if (err)
|
||||||
@ -1218,12 +1184,14 @@ imgtoolerr_t imgtool_image_create(const imgtool_module *module, const char *fnam
|
|||||||
/* allocate dummy options if necessary */
|
/* allocate dummy options if necessary */
|
||||||
if (!opts && module->createimage_optguide)
|
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; }
|
catch (...) { return (imgtoolerr_t)IMGTOOLERR_OUTOFMEMORY; }
|
||||||
|
|
||||||
|
if (module->createimage_optspec)
|
||||||
|
alloc_resolution->set_specification(module->createimage_optspec);
|
||||||
|
|
||||||
opts = alloc_resolution.get();
|
opts = alloc_resolution.get();
|
||||||
}
|
}
|
||||||
if (opts)
|
|
||||||
opts->finish();
|
|
||||||
|
|
||||||
return internal_open(module, fname, OSD_FOPEN_RW_CREATE, opts, image);
|
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 */
|
/* allocate dummy options if necessary */
|
||||||
if (!opts && partition->writefile_optguide)
|
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 (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
err = IMGTOOLERR_OUTOFMEMORY;
|
err = IMGTOOLERR_OUTOFMEMORY;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (partition->writefile_optspec)
|
||||||
|
alloc_resolution->set_specification(partition->writefile_optspec);
|
||||||
opts = alloc_resolution.get();
|
opts = alloc_resolution.get();
|
||||||
}
|
}
|
||||||
if (opts)
|
|
||||||
opts->finish();
|
|
||||||
|
|
||||||
/* if free_space is implemented; do a quick check to see if space is available */
|
/* if free_space is implemented; do a quick check to see if space is available */
|
||||||
if (partition->free_space)
|
if (partition->free_space)
|
||||||
|
@ -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->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->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->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->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);
|
module->image_extra_bytes += imgtool_get_info_int(imgclass, IMGTOOLINFO_INT_IMAGE_EXTRA_BYTES);
|
||||||
}
|
}
|
||||||
|
@ -291,8 +291,8 @@ union imgtoolinfo
|
|||||||
int (*approve_filename_char)(unicode_char ch);
|
int (*approve_filename_char)(unicode_char ch);
|
||||||
int (*make_class)(int index, imgtool_class *imgclass);
|
int (*make_class)(int index, imgtool_class *imgclass);
|
||||||
|
|
||||||
const option_guide *createimage_optguide;
|
const util::option_guide *createimage_optguide;
|
||||||
const option_guide *writefile_optguide;
|
const util::option_guide *writefile_optguide;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -369,7 +369,7 @@ struct imgtool_module
|
|||||||
|
|
||||||
UINT32 block_size;
|
UINT32 block_size;
|
||||||
|
|
||||||
const option_guide *createimage_optguide;
|
const util::option_guide *createimage_optguide;
|
||||||
const char *createimage_optspec;
|
const char *createimage_optspec;
|
||||||
|
|
||||||
const void *extra;
|
const void *extra;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// copyright-holders:Nathan Woods
|
// copyright-holders:Nathan Woods
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
|
|
||||||
main.c
|
main.cpp
|
||||||
|
|
||||||
Imgtool command line front end
|
Imgtool command line front end
|
||||||
|
|
||||||
@ -17,6 +17,8 @@
|
|||||||
#include "imgtool.h"
|
#include "imgtool.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "modules.h"
|
#include "modules.h"
|
||||||
|
#include "strformat.h"
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
static void writeusage(FILE *f, int write_word_usage, const struct command *c, char *argv[])
|
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 *s;
|
||||||
char *name = nullptr;
|
char *name = nullptr;
|
||||||
char *value = nullptr;
|
char *value = nullptr;
|
||||||
util::option_resolution::error oerr;
|
|
||||||
static char buf[256];
|
static char buf[256];
|
||||||
|
|
||||||
if (filter)
|
if (filter)
|
||||||
@ -97,9 +98,7 @@ static int parse_options(int argc, char *argv[], int minunnamed, int maxunnamed,
|
|||||||
if (i < minunnamed)
|
if (i < minunnamed)
|
||||||
goto error; /* Too few unnamed */
|
goto error; /* Too few unnamed */
|
||||||
|
|
||||||
oerr = resolution->add_param(name, value);
|
resolution->find(name)->set_value(value);
|
||||||
if (oerr != util::option_resolution::error::SUCCESS)
|
|
||||||
goto opterror;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,10 +112,6 @@ optionalreadyspecified:
|
|||||||
fprintf(stderr, "Cannot specify multiple %ss\n", name);
|
fprintf(stderr, "Cannot specify multiple %ss\n", name);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
opterror:
|
|
||||||
fprintf(stderr, "%s: %s\n", name, util::option_resolution::error_string(oerr));
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
error:
|
error:
|
||||||
fprintf(stderr, "%s: Unrecognized option\n", argv[i]);
|
fprintf(stderr, "%s: Unrecognized option\n", argv[i]);
|
||||||
return -1;
|
return -1;
|
||||||
@ -328,7 +323,7 @@ static int cmd_put(const struct command *c, int argc, char *argv[])
|
|||||||
char **filename_list;
|
char **filename_list;
|
||||||
int filename_count;
|
int filename_count;
|
||||||
int partition_index = 0;
|
int partition_index = 0;
|
||||||
const option_guide *writefile_optguide;
|
const util::option_guide *writefile_optguide;
|
||||||
const char *writefile_optspec;
|
const char *writefile_optspec;
|
||||||
|
|
||||||
module = imgtool_find_module(argv[0]);
|
module = imgtool_find_module(argv[0]);
|
||||||
@ -353,17 +348,18 @@ static int cmd_put(const struct command *c, int argc, char *argv[])
|
|||||||
if (err)
|
if (err)
|
||||||
goto done;
|
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);
|
writefile_optspec = (const char *)imgtool_partition_get_info_ptr(partition, IMGTOOLINFO_STR_WRITEFILE_OPTSPEC);
|
||||||
|
|
||||||
if (writefile_optguide && 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 (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
err = IMGTOOLERR_OUTOFMEMORY;
|
err = IMGTOOLERR_OUTOFMEMORY;
|
||||||
goto done;
|
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)
|
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 (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
err = IMGTOOLERR_OUTOFMEMORY;
|
err = IMGTOOLERR_OUTOFMEMORY;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
resolution->set_specification(module->createimage_optspec);
|
||||||
}
|
}
|
||||||
|
|
||||||
unnamedargs = parse_options(argc, argv, 2, 3, resolution.get(), nullptr, nullptr);
|
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;
|
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];
|
util::option_resolution resolution(opt_guide);
|
||||||
const char *opt_desc;
|
resolution.set_specification(opt_spec);
|
||||||
util::option_resolution::range range[32];
|
|
||||||
char range_buffer[512];
|
|
||||||
char buf[32];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
assert(opt_guide);
|
|
||||||
|
|
||||||
fprintf(stdout, "Option Allowed values Description\n");
|
fprintf(stdout, "Option Allowed values Description\n");
|
||||||
fprintf(stdout, "---------------- ------------------------------ -----------\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;
|
const auto &entry = *iter;
|
||||||
snprintf(opt_name, ARRAY_LENGTH(opt_name), "--%s", opt_guide->identifier);
|
std::stringstream description_buffer;
|
||||||
opt_desc = opt_guide->display_name;
|
|
||||||
|
|
||||||
/* is this option relevant? */
|
std::string opt_name = string_format("--%s", entry.identifier());
|
||||||
if (!strchr(opt_spec, opt_guide->parameter))
|
const char *opt_desc = entry.display_name();
|
||||||
{
|
|
||||||
opt_guide++;
|
// is this option relevant?
|
||||||
|
if (!strchr(opt_spec, entry.parameter()))
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
switch(opt_guide->option_type) {
|
switch (entry.option_type())
|
||||||
case OPTIONTYPE_INT:
|
{
|
||||||
util::option_resolution::list_ranges(opt_spec, opt_guide->parameter,
|
case util::option_guide::entry::option_type::INT:
|
||||||
range, ARRAY_LENGTH(range));
|
for (const auto &range : entry.ranges())
|
||||||
|
|
||||||
for (i = 0; range[i].max >= 0; i++)
|
|
||||||
{
|
{
|
||||||
if (range[i].min == range[i].max)
|
if (!description_buffer.str().empty())
|
||||||
snprintf(buf, ARRAY_LENGTH(buf), "%i", range[i].min);
|
description_buffer << "/";
|
||||||
|
|
||||||
|
if (range.min == range.max)
|
||||||
|
util::stream_format(description_buffer, "%d", range.min);
|
||||||
else
|
else
|
||||||
snprintf(buf, ARRAY_LENGTH(buf), "%i-%i", range[i].min, range[i].max);
|
util::stream_format(description_buffer, "%d-%d", range.min, range.max);
|
||||||
|
|
||||||
if (i > 0)
|
|
||||||
strncatz(range_buffer, "/", sizeof(range_buffer));
|
|
||||||
strncatz(range_buffer, buf, sizeof(range_buffer));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPTIONTYPE_ENUM_BEGIN:
|
case util::option_guide::entry::option_type::ENUM_BEGIN:
|
||||||
i = 0;
|
for (auto enum_value = entry.enum_value_begin(); enum_value != entry.enum_value_end(); enum_value++)
|
||||||
while(opt_guide[1].option_type == OPTIONTYPE_ENUM_VALUE)
|
|
||||||
{
|
{
|
||||||
if (i > 0)
|
if (!description_buffer.str().empty())
|
||||||
strncatz(range_buffer, "/", sizeof(range_buffer));
|
description_buffer << "/";
|
||||||
strncatz(range_buffer, opt_guide[1].identifier, sizeof(range_buffer));
|
description_buffer << enum_value->identifier();
|
||||||
|
|
||||||
opt_guide++;
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPTIONTYPE_STRING:
|
case util::option_guide::entry::option_type::STRING:
|
||||||
snprintf(range_buffer, sizeof(range_buffer), "(string)");
|
description_buffer << "(string)";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stdout, "%16s %-30s %s\n",
|
fprintf(stdout, "%16s %-30s %s\n",
|
||||||
opt_name,
|
opt_name.c_str(),
|
||||||
range_buffer,
|
description_buffer.str().c_str(),
|
||||||
opt_desc);
|
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[])
|
static int cmd_listdriveroptions(const struct command *c, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
const imgtool_module *mod;
|
const imgtool_module *mod;
|
||||||
const option_guide *opt_guide;
|
const util::option_guide *opt_guide;
|
||||||
const char *opt_spec;
|
const char *opt_spec;
|
||||||
|
|
||||||
mod = imgtool_find_module(argv[0]);
|
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]);
|
fprintf(stdout, "Driver specific options for module '%s':\n\n", argv[0]);
|
||||||
|
|
||||||
/* list write options */
|
/* 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);
|
opt_spec = imgtool_get_info_string(&mod->imgclass, IMGTOOLINFO_STR_WRITEFILE_OPTSPEC);
|
||||||
if (opt_guide)
|
if (opt_guide)
|
||||||
{
|
{
|
||||||
fprintf(stdout, "Image specific file options (usable on the 'put' command):\n\n");
|
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");
|
puts("\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -852,7 +836,7 @@ static int cmd_listdriveroptions(const struct command *c, int argc, char *argv[]
|
|||||||
if (opt_guide)
|
if (opt_guide)
|
||||||
{
|
{
|
||||||
fprintf(stdout, "Image specific creation options (usable on the 'create' command):\n\n");
|
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");
|
puts("\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -940,7 +924,7 @@ int CLIB_DECL main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Usage */
|
/* 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++)
|
for (i = 0; i < ARRAY_LENGTH(cmds); i++)
|
||||||
{
|
{
|
||||||
writeusage(stdout, (i == 0), &cmds[i], argv);
|
writeusage(stdout, (i == 0), &cmds[i], argv);
|
||||||
|
@ -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)
|
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);
|
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;
|
imgtoolerr_t ret;
|
||||||
UINT8 buffer[BSIZE];
|
UINT8 buffer[BSIZE];
|
||||||
root_block root;
|
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);
|
amiga_setup_time(now, &root.c);
|
||||||
|
|
||||||
/* volume name */
|
/* volume name */
|
||||||
if (dskname)
|
if (!dskname.empty())
|
||||||
{
|
{
|
||||||
root.name_len = strlen(dskname);
|
root.name_len = dskname.length();
|
||||||
memcpy(&root.diskname, dskname, root.name_len);
|
memcpy(&root.diskname, dskname.c_str(), root.name_len);
|
||||||
}
|
}
|
||||||
else
|
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_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_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_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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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_WRITE_FILE: info->write_file = bml3_diskimage_writefile; break;
|
||||||
case IMGTOOLINFO_PTR_DELETE_FILE: info->delete_file = bml3_diskimage_deletefile; 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_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;
|
case IMGTOOLINFO_PTR_FLOPPY_FORMAT: info->p = (void *) floppyoptions_default; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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_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_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_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;
|
// case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE : info->writefile_optguide = cybiko_image_writefile_optguide; break;
|
||||||
// --- the following bits of info are returned as NULL-terminated strings ---
|
// --- the following bits of info are returned as NULL-terminated strings ---
|
||||||
case IMGTOOLINFO_STR_NAME : strcpy( info->s = imgtool_temp_str(), "cybiko"); break;
|
case IMGTOOLINFO_STR_NAME : strcpy( info->s = imgtool_temp_str(), "cybiko"); break;
|
||||||
|
@ -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_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_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 --- */
|
/* --- the following bits of info are returned as pointers to data or functions --- */
|
||||||
case IMGTOOLINFO_PTR_OPEN: info->open = hp48_open; break;
|
case IMGTOOLINFO_PTR_OPEN: info->open = hp48_open; break;
|
||||||
|
@ -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_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_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_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_GET_GEOMETRY: info->get_geometry = pc_chd_image_get_geometry; break;
|
||||||
case IMGTOOLINFO_PTR_LIST_PARTITIONS: info->list_partitions = pc_chd_list_partitions; break;
|
case IMGTOOLINFO_PTR_LIST_PARTITIONS: info->list_partitions = pc_chd_list_partitions; break;
|
||||||
}
|
}
|
||||||
|
@ -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_READ_FILE : info->read_file = datapack_read_file; break;
|
||||||
case IMGTOOLINFO_PTR_WRITE_FILE : info->write_file = datapack_write_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_DELETE_FILE : info->delete_file = datapack_delete_file; break;
|
||||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE : info->createimage_optguide = psion_create_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;
|
case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE : info->createimage_optguide = &psion_write_optguide; break;
|
||||||
|
|
||||||
// --- the following bits of info are returned as NULL-terminated strings ---
|
// --- the following bits of info are returned as NULL-terminated strings ---
|
||||||
case IMGTOOLINFO_STR_NAME : strcpy( info->s = imgtool_temp_str(), "psionpack"); break;
|
case IMGTOOLINFO_STR_NAME : strcpy( info->s = imgtool_temp_str(), "psionpack"); break;
|
||||||
|
@ -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_WRITE_FILE: info->write_file = rsdos_diskimage_writefile; break;
|
||||||
case IMGTOOLINFO_PTR_DELETE_FILE: info->delete_file = rsdos_diskimage_deletefile; 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_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;
|
case IMGTOOLINFO_PTR_FLOPPY_FORMAT: info->p = (void *) floppyoptions_coco; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1065,7 +1065,7 @@ static imgtoolerr_t thom_write_file(imgtool_partition *part,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* comment */
|
/* comment */
|
||||||
char const *const comment = opts->lookup_string('C');
|
char const *const comment = opts->lookup_string('C').c_str();
|
||||||
if (comment && *comment)
|
if (comment && *comment)
|
||||||
strncpy(d.comment, comment, 8);
|
strncpy(d.comment, comment, 8);
|
||||||
|
|
||||||
@ -1132,7 +1132,7 @@ static imgtoolerr_t thom_create(imgtool_image* img,
|
|||||||
/* get parameters */
|
/* get parameters */
|
||||||
f->heads = opts->lookup_int('H');
|
f->heads = opts->lookup_int('H');
|
||||||
f->tracks = opts->lookup_int('T');
|
f->tracks = opts->lookup_int('T');
|
||||||
name = opts->lookup_string('N');
|
name = opts->lookup_string('N').c_str();
|
||||||
switch ( opts->lookup_int('D') ) {
|
switch ( opts->lookup_int('D') ) {
|
||||||
case 0: f->sector_size = 128; f->sectuse_size = 128; break;
|
case 0: f->sector_size = 128; f->sectuse_size = 128; break;
|
||||||
case 1: f->sector_size = 256; f->sectuse_size = 255; 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:
|
case IMGTOOLINFO_PTR_CREATE:
|
||||||
info->create = thom_create; break;
|
info->create = thom_create; break;
|
||||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE:
|
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE:
|
||||||
info->createimage_optguide = thom_createimage_optguide; break;
|
info->createimage_optguide = &thom_createimage_optguide; break;
|
||||||
case IMGTOOLINFO_PTR_BEGIN_ENUM:
|
case IMGTOOLINFO_PTR_BEGIN_ENUM:
|
||||||
info->begin_enum = thom_begin_enum; break;
|
info->begin_enum = thom_begin_enum; break;
|
||||||
case IMGTOOLINFO_PTR_NEXT_ENUM:
|
case IMGTOOLINFO_PTR_NEXT_ENUM:
|
||||||
@ -1581,7 +1581,7 @@ static void thom_basic_get_info(const imgtool_class *clas,
|
|||||||
case IMGTOOLINFO_PTR_WRITE_FILE:
|
case IMGTOOLINFO_PTR_WRITE_FILE:
|
||||||
info->write_file = thom_write_file; break;
|
info->write_file = thom_write_file; break;
|
||||||
case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE:
|
case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE:
|
||||||
info->writefile_optguide = thom_writefile_optguide; break;
|
info->writefile_optguide = &thom_writefile_optguide; break;
|
||||||
case IMGTOOLINFO_STR_WRITEFILE_OPTSPEC:
|
case IMGTOOLINFO_STR_WRITEFILE_OPTSPEC:
|
||||||
strcpy( info->s = imgtool_temp_str(), "T[0]-4;F[0]-2;C" ); break;
|
strcpy( info->s = imgtool_temp_str(), "T[0]-4;F[0]-2;C" ); break;
|
||||||
case IMGTOOLINFO_PTR_SUGGEST_TRANSFER:
|
case IMGTOOLINFO_PTR_SUGGEST_TRANSFER:
|
||||||
|
@ -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_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_OPEN: info->open = dsk_image_init_mess; break;
|
||||||
case IMGTOOLINFO_PTR_CREATE: info->create = dsk_image_create_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;
|
case IMGTOOLINFO_STR_CREATEIMAGE_OPTSPEC: strcpy(info->s = imgtool_temp_str(), dsk_create_optionspecs); break;
|
||||||
default: ti99_dsk_getinfo(imgclass, state, info); 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_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_OPEN: info->open = dsk_image_init_v9t9; break;
|
||||||
case IMGTOOLINFO_PTR_CREATE: info->create = dsk_image_create_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;
|
case IMGTOOLINFO_STR_CREATEIMAGE_OPTSPEC: strcpy(info->s = imgtool_temp_str(), dsk_create_optionspecs); break;
|
||||||
default: ti99_dsk_getinfo(imgclass, state, info); 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;
|
l1_img.file_handle = f;
|
||||||
|
|
||||||
/* read options */
|
/* 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.heads = createoptions->lookup_int(dsk_createopts_sides);
|
||||||
l1_img.geometry.cylinders = createoptions->lookup_int(dsk_createopts_tracks);
|
l1_img.geometry.cylinders = createoptions->lookup_int(dsk_createopts_tracks);
|
||||||
l1_img.geometry.secspertrack = createoptions->lookup_int(dsk_createopts_sectors);
|
l1_img.geometry.secspertrack = createoptions->lookup_int(dsk_createopts_sectors);
|
||||||
|
@ -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_DELETE_FILE: /* info->delete_file = ti990_image_deletefile; */ break;
|
||||||
case IMGTOOLINFO_PTR_CREATE: info->create = ti990_image_create; 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;
|
case IMGTOOLINFO_STR_CREATEIMAGE_OPTSPEC: strcpy(info->s = imgtool_temp_str(), ti990_create_optionspecs); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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_WRITE_FILE: info->write_file = vzdos_diskimage_writefile; break;
|
||||||
case IMGTOOLINFO_PTR_DELETE_FILE: info->delete_file = vzdos_diskimage_deletefile; 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_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_SUGGEST_TRANSFER: info->suggest_transfer = vzdos_diskimage_suggesttransfer; break;
|
||||||
case IMGTOOLINFO_PTR_FLOPPY_FORMAT: info->p = (void *) floppyoptions_vz; break;
|
case IMGTOOLINFO_PTR_FLOPPY_FORMAT: info->p = (void *) floppyoptions_vz; break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user