mirror of
https://github.com/holub/mame
synced 2025-04-24 01:11:11 +03:00
Merge pull request #1332 from npwoods/option_guide_and_imgtool
option_guide C++-ification, touched up imgtool
This commit is contained in:
commit
6a2b41aa0b
@ -10,7 +10,7 @@
|
||||
#include "diablo.h"
|
||||
|
||||
|
||||
static OPTION_GUIDE_START(dsk_option_guide)
|
||||
OPTION_GUIDE_START(dsk_option_guide)
|
||||
OPTION_INT('C', "cylinders", "Cylinders")
|
||||
OPTION_INT('H', "heads", "Heads")
|
||||
OPTION_INT('S', "sectors", "Sectors")
|
||||
@ -62,7 +62,7 @@ void diablo_image_device::device_config_complete()
|
||||
update_names();
|
||||
}
|
||||
|
||||
const option_guide *diablo_image_device::create_option_guide() const
|
||||
const util::option_guide &diablo_image_device::create_option_guide() const
|
||||
{
|
||||
return dsk_option_guide;
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ public:
|
||||
virtual bool is_reset_on_load() const override { return 0; }
|
||||
virtual const char *image_interface() const override { return m_interface; }
|
||||
virtual const char *file_extensions() const override { return "chd,dsk"; }
|
||||
virtual const option_guide *create_option_guide() const override;
|
||||
virtual const util::option_guide &create_option_guide() const override;
|
||||
|
||||
// specific implementation
|
||||
hard_disk_file *get_hard_disk_file() { return m_hard_disk_handle; }
|
||||
|
@ -114,7 +114,7 @@ public:
|
||||
virtual bool is_reset_on_load() const override { return 0; }
|
||||
virtual const char *image_interface() const override;
|
||||
virtual const char *file_extensions() const override { return m_extension_list; }
|
||||
virtual const option_guide *create_option_guide() const override { return floppy_option_guide; }
|
||||
virtual const util::option_guide &create_option_guide() const override { return floppy_option_guide; }
|
||||
|
||||
floppy_image_legacy *flopimg_get_image();
|
||||
void floppy_drive_set_geometry(floppy_type_t type);
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include "harddriv.h"
|
||||
|
||||
|
||||
static OPTION_GUIDE_START(hd_option_guide)
|
||||
OPTION_GUIDE_START(hd_option_guide)
|
||||
OPTION_INT('C', "cylinders", "Cylinders")
|
||||
OPTION_INT('H', "heads", "Heads")
|
||||
OPTION_INT('S', "sectors", "Sectors")
|
||||
@ -85,7 +85,7 @@ void harddisk_image_device::device_config_complete()
|
||||
update_names();
|
||||
}
|
||||
|
||||
const option_guide *harddisk_image_device::create_option_guide() const
|
||||
const util::option_guide &harddisk_image_device::create_option_guide() const
|
||||
{
|
||||
return hd_option_guide;
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ public:
|
||||
virtual bool is_reset_on_load() const override { return 0; }
|
||||
virtual const char *image_interface() const override { return m_interface; }
|
||||
virtual const char *file_extensions() const override { return "chd,hd"; }
|
||||
virtual const option_guide *create_option_guide() const override;
|
||||
virtual const util::option_guide &create_option_guide() const override;
|
||||
|
||||
// specific implementation
|
||||
hard_disk_file *get_hard_disk_file() { return m_hard_disk_handle; }
|
||||
|
@ -1263,6 +1263,18 @@ void device_image_interface::unload()
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// create_option_guide
|
||||
//-------------------------------------------------
|
||||
|
||||
OPTION_GUIDE_START(null_option_guide)
|
||||
OPTION_GUIDE_END
|
||||
|
||||
const util::option_guide &device_image_interface::create_option_guide() const
|
||||
{
|
||||
return null_option_guide;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// update_names - update brief and instance names
|
||||
//-------------------------------------------------
|
||||
|
@ -161,11 +161,11 @@ public:
|
||||
virtual bool support_command_line_image_creation() const;
|
||||
virtual const char *image_interface() const { return nullptr; }
|
||||
virtual const char *file_extensions() const = 0;
|
||||
virtual const option_guide *create_option_guide() const { return nullptr; }
|
||||
virtual const util::option_guide &create_option_guide() const;
|
||||
|
||||
const image_device_format *device_get_indexed_creatable_format(int index) const { if (index < m_formatlist.size()) return m_formatlist.at(index).get(); else return nullptr; }
|
||||
const image_device_format *device_get_named_creatable_format(const std::string &format_name);
|
||||
const option_guide *device_get_creation_option_guide() const { return create_option_guide(); }
|
||||
const util::option_guide &device_get_creation_option_guide() const { return create_option_guide(); }
|
||||
|
||||
const char *error();
|
||||
void seterror(image_error_t err, const char *message);
|
||||
|
@ -204,35 +204,9 @@ floperr_t floppy_open_choices(void *fp, const struct io_procs *procs, const std:
|
||||
|
||||
|
||||
|
||||
static floperr_t option_to_floppy_error(util::option_resolution::error oerr)
|
||||
{
|
||||
floperr_t err;
|
||||
switch(oerr) {
|
||||
case util::option_resolution::error::SUCCESS:
|
||||
err = FLOPPY_ERROR_SUCCESS;
|
||||
break;
|
||||
case util::option_resolution::error::OUTOFMEMORY:
|
||||
err = FLOPPY_ERROR_OUTOFMEMORY;
|
||||
break;
|
||||
case util::option_resolution::error::PARAMOUTOFRANGE:
|
||||
case util::option_resolution::error::PARAMNOTSPECIFIED:
|
||||
case util::option_resolution::error::PARAMNOTFOUND:
|
||||
case util::option_resolution::error::PARAMALREADYSPECIFIED:
|
||||
case util::option_resolution::error::BADPARAM:
|
||||
case util::option_resolution::error::SYNTAX:
|
||||
default:
|
||||
err = FLOPPY_ERROR_INTERNAL;
|
||||
break;
|
||||
};
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
floperr_t floppy_create(void *fp, const struct io_procs *procs, const struct FloppyFormat *format, util::option_resolution *parameters, floppy_image_legacy **outfloppy)
|
||||
{
|
||||
floppy_image_legacy *floppy = nullptr;
|
||||
util::option_resolution::error oerr;
|
||||
floperr_t err;
|
||||
int heads, tracks, h, t;
|
||||
std::unique_ptr<util::option_resolution> alloc_resolution;
|
||||
@ -250,26 +224,16 @@ floperr_t floppy_create(void *fp, const struct io_procs *procs, const struct Flo
|
||||
/* if this format expects creation parameters and none were specified, create some */
|
||||
if (!parameters && format->param_guidelines)
|
||||
{
|
||||
alloc_resolution = std::make_unique<util::option_resolution>(floppy_option_guide, format->param_guidelines);
|
||||
if (!alloc_resolution)
|
||||
try { alloc_resolution = std::make_unique<util::option_resolution>(floppy_option_guide); }
|
||||
catch (...)
|
||||
{
|
||||
err = FLOPPY_ERROR_OUTOFMEMORY;
|
||||
goto done;
|
||||
}
|
||||
alloc_resolution->set_specification(format->param_guidelines);
|
||||
parameters = alloc_resolution.get();
|
||||
}
|
||||
|
||||
/* finish the parameters, if specified */
|
||||
if (parameters)
|
||||
{
|
||||
oerr = parameters->finish();
|
||||
if (oerr != util::option_resolution::error::SUCCESS)
|
||||
{
|
||||
err = option_to_floppy_error(oerr);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* call the format constructor */
|
||||
err = format->construct(floppy, format, parameters);
|
||||
if (err)
|
||||
@ -690,17 +654,19 @@ floperr_t floppy_format_track(floppy_image_legacy *floppy, int head, int track,
|
||||
/* create a dummy resolution; if no parameters were specified */
|
||||
if (!parameters)
|
||||
{
|
||||
alloc_resolution = std::make_unique<util::option_resolution>(floppy_option_guide, floppy->floppy_option->param_guidelines);
|
||||
if (!alloc_resolution)
|
||||
try
|
||||
{
|
||||
alloc_resolution = std::make_unique<util::option_resolution>(floppy_option_guide);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return FLOPPY_ERROR_OUTOFMEMORY;
|
||||
}
|
||||
alloc_resolution->set_specification(floppy->floppy_option->param_guidelines);
|
||||
|
||||
parameters = alloc_resolution.get();
|
||||
}
|
||||
|
||||
auto oerr = parameters->finish();
|
||||
if (oerr != util::option_resolution::error::SUCCESS)
|
||||
return option_to_floppy_error(oerr);
|
||||
|
||||
err = format->format_track(floppy, head, track, parameters);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -2,7 +2,7 @@
|
||||
// copyright-holders:Nathan Woods
|
||||
/****************************************************************************
|
||||
|
||||
opresolv.h
|
||||
opresolv.cpp
|
||||
|
||||
Extensible ranged option resolution handling
|
||||
|
||||
@ -19,226 +19,51 @@
|
||||
|
||||
|
||||
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.end() - guide.begin());
|
||||
|
||||
|
||||
// -------------------------------------------------
|
||||
// entry::set_int_value
|
||||
// -------------------------------------------------
|
||||
|
||||
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))
|
||||
// initialize each of the entries; can't use foreach because we need to scan the
|
||||
// ENUM_VALUE entries
|
||||
for (auto iter = guide.begin(); iter != guide.end(); iter++)
|
||||
{
|
||||
if (*s == '-')
|
||||
{
|
||||
/* range specifier */
|
||||
if (flags & (FLAG_IN_RANGE|FLAG_IN_DEFAULT))
|
||||
{
|
||||
return error::SYNTAX;
|
||||
}
|
||||
flags |= FLAG_IN_RANGE;
|
||||
s++;
|
||||
// create the entry
|
||||
m_entries.emplace_back(*iter);
|
||||
entry &entry(m_entries.back());
|
||||
|
||||
if (range)
|
||||
{
|
||||
range->max = -1;
|
||||
if ((flags & FLAG_HALF_RANGE) == 0)
|
||||
{
|
||||
range->min = -1;
|
||||
flags |= FLAG_HALF_RANGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*s == '[')
|
||||
// if this is an enumeration, identify the values
|
||||
if (iter->type() == option_guide::entry::option_type::ENUM_BEGIN)
|
||||
{
|
||||
/* begin default value */
|
||||
if (flags & (FLAG_IN_DEFAULT|FLAG_DEFAULT_SPECIFIED))
|
||||
{
|
||||
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++;
|
||||
// enum values begin after the ENUM_BEGIN
|
||||
auto enum_value_begin = iter + 1;
|
||||
auto enum_value_end = enum_value_begin;
|
||||
|
||||
if (param_value && param_value->int_value() == -1)
|
||||
param_value->set_int_value(value);
|
||||
}
|
||||
else if (*s == '/')
|
||||
{
|
||||
/* value separator */
|
||||
if (flags & (FLAG_IN_DEFAULT|FLAG_IN_RANGE))
|
||||
// and identify all entries of type ENUM_VALUE
|
||||
while (enum_value_end != guide.end() && enum_value_end->type() == option_guide::entry::option_type::ENUM_VALUE)
|
||||
{
|
||||
return error::SYNTAX;
|
||||
}
|
||||
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;
|
||||
iter++;
|
||||
enum_value_end++;
|
||||
}
|
||||
|
||||
// if we have a value; check to see if it is out of range
|
||||
if (param_value && (param_value->int_value() != -1) && (param_value->int_value() != value))
|
||||
{
|
||||
if ((last_value < param_value->int_value()) && (param_value->int_value() < value))
|
||||
{
|
||||
if ((flags & FLAG_IN_RANGE) == 0)
|
||||
return error::PARAMOUTOFRANGE;
|
||||
}
|
||||
}
|
||||
flags &= ~FLAG_IN_RANGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return error::SYNTAX;
|
||||
// set the range
|
||||
entry.set_enum_value_range(enum_value_begin, enum_value_end);
|
||||
}
|
||||
}
|
||||
|
||||
// we can't have zero length guidelines strings
|
||||
if (s == specification)
|
||||
{
|
||||
return error::SYNTAX;
|
||||
}
|
||||
|
||||
return error::SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------
|
||||
// lookup_in_specification
|
||||
// -------------------------------------------------
|
||||
|
||||
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
|
||||
// dtor
|
||||
// -------------------------------------------------
|
||||
|
||||
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;
|
||||
bool must_resolve;
|
||||
error err;
|
||||
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;
|
||||
const char *s;
|
||||
s = strchr(specification, option.parameter());
|
||||
return s ? s + 1 : nullptr;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------
|
||||
// finish
|
||||
// set_specification - sets the option specification
|
||||
// and mutates values accordingly
|
||||
// -------------------------------------------------
|
||||
|
||||
option_resolution::error option_resolution::finish()
|
||||
{
|
||||
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
|
||||
void option_resolution::set_specification(const std::string &specification)
|
||||
{
|
||||
for (auto &entry : m_entries)
|
||||
{
|
||||
switch(entry.guide_entry->option_type) {
|
||||
case OPTIONTYPE_INT:
|
||||
case OPTIONTYPE_STRING:
|
||||
case OPTIONTYPE_ENUM_BEGIN:
|
||||
if (entry.guide_entry->parameter == option_char)
|
||||
return &entry;
|
||||
break;
|
||||
// find this entry's info in the specification
|
||||
auto entry_specification = lookup_in_specification(specification.c_str(), entry.m_guide_entry);
|
||||
|
||||
default:
|
||||
assert(FALSE);
|
||||
return nullptr;
|
||||
// parse this entry's specification (e.g. - set up ranges and defaults)
|
||||
entry.parse_specification(entry_specification);
|
||||
|
||||
// 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);
|
||||
return entry ? entry->int_value() : -1;
|
||||
auto iter = std::find_if(
|
||||
m_entries.begin(),
|
||||
m_entries.end(),
|
||||
[parameter](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);
|
||||
return entry ? entry->value.c_str() : nullptr;
|
||||
auto iter = std::find_if(
|
||||
m_entries.begin(),
|
||||
m_entries.end(),
|
||||
[&](const entry &e) { return !strcmp(e.identifier(), identifier.c_str()); });
|
||||
|
||||
return iter != m_entries.end()
|
||||
? &*iter
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------
|
||||
// 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);
|
||||
return entry ? entry->guide_entry : nullptr;
|
||||
auto entry = find(parameter);
|
||||
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()))
|
||||
return nullptr;
|
||||
return m_entries[indx].guide_entry;
|
||||
auto entry = find(parameter);
|
||||
assert(entry != nullptr);
|
||||
return entry->value();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------
|
||||
// count_options
|
||||
// -------------------------------------------------
|
||||
|
||||
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
|
||||
// error_string
|
||||
// -------------------------------------------------
|
||||
|
||||
option_resolution::error option_resolution::get_default(const char *specification, int option_char, int *val)
|
||||
{
|
||||
assert(val);
|
||||
|
||||
// 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;
|
||||
// NYI
|
||||
return error::INTERNAL;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------
|
||||
// list_ranges
|
||||
// -------------------------------------------------
|
||||
|
||||
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
|
||||
// error_string
|
||||
// -------------------------------------------------
|
||||
|
||||
const char *option_resolution::error_string(option_resolution::error err)
|
||||
{
|
||||
switch (err)
|
||||
{
|
||||
case error::SUCCESS: return "The operation completed successfully";
|
||||
case error::OUTOFMEMORY: return "Out of memory";
|
||||
case error::PARAMOUTOFRANGE: return "Parameter out of range";
|
||||
case error::PARAMNOTSPECIFIED: return "Parameter not specified";
|
||||
case error::PARAMNOTFOUND: return "Unknown parameter";
|
||||
case error::PARAMALREADYSPECIFIED: return "Parameter specified multiple times";
|
||||
case error::BADPARAM: return "Invalid parameter";
|
||||
case error::SYNTAX: return "Syntax error";
|
||||
case error::INTERNAL: return "Internal error";
|
||||
case error::SUCCESS: return "The operation completed successfully";
|
||||
case error::OUTOFMEMORY: return "Out of memory";
|
||||
case error::PARAMOUTOFRANGE: return "Parameter out of range";
|
||||
case error::PARAMNOTSPECIFIED: return "Parameter not specified";
|
||||
case error::PARAMNOTFOUND: return "Unknown parameter";
|
||||
case error::PARAMALREADYSPECIFIED: return "Parameter specified multiple times";
|
||||
case error::BADPARAM: return "Invalid parameter";
|
||||
case error::SYNTAX: return "Syntax error";
|
||||
case error::INTERNAL: return "Internal error";
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // 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(const option_guide::entry *begin, const option_guide::entry *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 - abort because we cannot recover from this syntax error
|
||||
throw false;
|
||||
}
|
||||
}
|
||||
|
||||
// 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,116 @@
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
enum option_type
|
||||
{
|
||||
OPTIONTYPE_END,
|
||||
OPTIONTYPE_INT,
|
||||
OPTIONTYPE_STRING,
|
||||
OPTIONTYPE_ENUM_BEGIN,
|
||||
OPTIONTYPE_ENUM_VALUE
|
||||
};
|
||||
|
||||
struct option_guide
|
||||
{
|
||||
enum option_type option_type;
|
||||
int parameter;
|
||||
const char *identifier;
|
||||
const char *display_name;
|
||||
};
|
||||
|
||||
#define OPTION_GUIDE_START(option_guide_) \
|
||||
const option_guide option_guide_[] = \
|
||||
{
|
||||
#define OPTION_GUIDE_END \
|
||||
{ OPTIONTYPE_END } \
|
||||
};
|
||||
#define OPTION_GUIDE_EXTERN(option_guide_) \
|
||||
extern const option_guide option_guide_[]
|
||||
#define OPTION_INT(option_char, identifier, display_name) \
|
||||
{ OPTIONTYPE_INT, (option_char), (identifier), (display_name) },
|
||||
#define OPTION_STRING(option_char, identifier, display_name) \
|
||||
{ OPTIONTYPE_STRING, (option_char), (identifier), (display_name) },
|
||||
#define OPTION_ENUM_START(option_char, identifier, display_name) \
|
||||
{ OPTIONTYPE_ENUM_BEGIN, (option_char), (identifier), (display_name) },
|
||||
#define OPTION_ENUM(value, identifier, display_name) \
|
||||
{ OPTIONTYPE_ENUM_VALUE, (value), (identifier), (display_name) },
|
||||
#define OPTION_GUIDE_START(option_guide_) \
|
||||
namespace option_guide_impl_##option_guide_ \
|
||||
{ \
|
||||
static const util::option_guide &get(); \
|
||||
}; \
|
||||
const util::option_guide &option_guide_ = option_guide_impl_##option_guide_::get(); \
|
||||
namespace option_guide_impl_##option_guide_ \
|
||||
{ \
|
||||
static const auto actual = util::make_option_guide(0
|
||||
#define OPTION_GUIDE_END \
|
||||
); \
|
||||
static const util::option_guide &get() { return actual; } \
|
||||
};
|
||||
#define OPTION_GUIDE_EXTERN(option_guide_) \
|
||||
extern const util::option_guide &option_guide_
|
||||
#define OPTION_INT(option_char, identifier, display_name) \
|
||||
,util::option_guide::entry(util::option_guide::entry::option_type::INT, (option_char), (identifier), (display_name))
|
||||
#define OPTION_STRING(option_char, identifier, display_name) \
|
||||
,util::option_guide::entry(util::option_guide::entry::option_type::STRING, (option_char), (identifier), (display_name))
|
||||
#define OPTION_ENUM_START(option_char, identifier, display_name) \
|
||||
,util::option_guide::entry(util::option_guide::entry::option_type::ENUM_BEGIN, (option_char), (identifier), (display_name))
|
||||
#define OPTION_ENUM(value, identifier, display_name) \
|
||||
,util::option_guide::entry(util::option_guide::entry::option_type::ENUM_VALUE, (value), (identifier), (display_name))
|
||||
#define OPTION_ENUM_END
|
||||
|
||||
namespace util {
|
||||
|
||||
// ======================> option_guide
|
||||
|
||||
class option_guide
|
||||
{
|
||||
public:
|
||||
class entry
|
||||
{
|
||||
public:
|
||||
enum class option_type
|
||||
{
|
||||
INVALID,
|
||||
INT,
|
||||
STRING,
|
||||
ENUM_BEGIN,
|
||||
ENUM_VALUE
|
||||
};
|
||||
|
||||
constexpr entry()
|
||||
: m_type(option_type::INVALID), m_parameter(0), m_identifier(nullptr), m_display_name(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
// methods
|
||||
const entry *begin() const { return m_begin; }
|
||||
const entry *end() const { return m_end; }
|
||||
|
||||
protected:
|
||||
option_guide(const entry *begin, const entry *end)
|
||||
: m_begin(begin), m_end(end)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
const entry *m_begin;
|
||||
const entry *m_end;
|
||||
};
|
||||
|
||||
// ======================> option_guide_impl
|
||||
|
||||
template <std::size_t Count>
|
||||
class option_guide_impl : protected std::array<option_guide::entry, Count>, public option_guide
|
||||
{
|
||||
public:
|
||||
template<typename... T>
|
||||
option_guide_impl(T &&... elems)
|
||||
: std::array<option_guide::entry, Count>({ std::forward<T>(elems)... })
|
||||
, option_guide(&(*this)[0], &(*this)[0] + Count)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... T>
|
||||
option_guide_impl<sizeof...(T)> make_option_guide(int dummy, T &&... elems)
|
||||
{
|
||||
return option_guide_impl<sizeof...(T)>(std::forward<T>(elems)...);
|
||||
}
|
||||
|
||||
|
||||
// ======================> option_resolution
|
||||
|
||||
class option_resolution
|
||||
{
|
||||
public:
|
||||
// TODO - audit unused parameters
|
||||
enum class error
|
||||
{
|
||||
SUCCESS,
|
||||
@ -102,61 +173,98 @@ public:
|
||||
INTERNAL
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct range
|
||||
{
|
||||
int min, max;
|
||||
range() { min = -1; max = -1; }
|
||||
T min, max;
|
||||
};
|
||||
|
||||
option_resolution(const option_guide *guide, const char *specification);
|
||||
// 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::entry *enum_value_begin() const { return m_enum_value_begin; }
|
||||
const option_guide::entry *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;
|
||||
const option_guide::entry * m_enum_value_begin;
|
||||
const option_guide::entry * 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(const option_guide::entry *begin, const option_guide::entry *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();
|
||||
|
||||
// processing options with option_resolution objects
|
||||
error add_param(const char *param, const std::string &value);
|
||||
error finish();
|
||||
int lookup_int(int option_char) const;
|
||||
const char *lookup_string(int option_char) const;
|
||||
// sets a specification
|
||||
void set_specification(const std::string &specification);
|
||||
|
||||
// accessors
|
||||
const char *specification() const { return m_specification; }
|
||||
const option_guide *find_option(int option_char) const;
|
||||
const option_guide *index_option(int indx) const;
|
||||
|
||||
// processing option guides
|
||||
static size_t count_options(const option_guide *guide, const char *specification);
|
||||
|
||||
// processing option specifications
|
||||
static error list_ranges(const char *specification, int option_char,
|
||||
range *range, size_t range_count);
|
||||
static error get_default(const char *specification, int option_char, int *val);
|
||||
static error is_valid_value(const char *specification, int option_char, int val);
|
||||
static bool contains(const char *specification, int option_char);
|
||||
// entry lookup - note that we're not exposing m_entries directly because we don't really
|
||||
// have a way of making the list be immutable but the members be mutable at the same time
|
||||
std::vector<entry>::iterator entries_begin() { return m_entries.begin(); }
|
||||
std::vector<entry>::iterator entries_end() { return m_entries.end(); }
|
||||
entry *find(int parameter);
|
||||
entry *find(const std::string &identifier);
|
||||
int lookup_int(int parameter);
|
||||
const std::string &lookup_string(int parameter);
|
||||
|
||||
// misc
|
||||
static const char *error_string(error err);
|
||||
static error get_default(const char *specification, int option_char, int *val);
|
||||
|
||||
private:
|
||||
enum class entry_state
|
||||
{
|
||||
UNSPECIFIED,
|
||||
SPECIFIED
|
||||
};
|
||||
|
||||
struct entry
|
||||
{
|
||||
const option_guide *guide_entry;
|
||||
entry_state state;
|
||||
std::string value;
|
||||
|
||||
int int_value() const;
|
||||
void set_int_value(int i);
|
||||
};
|
||||
|
||||
const char *m_specification;
|
||||
std::vector<entry> m_entries;
|
||||
|
||||
static error resolve_single_param(const char *specification, entry *param_value,
|
||||
struct range *range, size_t range_count);
|
||||
static const char *lookup_in_specification(const char *specification, const option_guide *option);
|
||||
error set_parameter(std::vector<entry>::iterator iter, const std::string &value);
|
||||
|
||||
static const char *lookup_in_specification(const char *specification, const option_guide::entry &option);
|
||||
const entry *lookup_entry(int option_char) const;
|
||||
};
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
||||
#define OPK_HEAD_SIZE 6
|
||||
|
||||
|
||||
static OPTION_GUIDE_START( datapack_option_guide )
|
||||
OPTION_GUIDE_START( datapack_option_guide )
|
||||
OPTION_INT('S', "size", "Datapack size" )
|
||||
OPTION_INT('R', "ram", "RAM/EPROM" )
|
||||
OPTION_INT('P', "paged", "Paged" )
|
||||
@ -105,7 +105,7 @@ void datapack_device::device_config_complete()
|
||||
// option_guide for create new image
|
||||
//-------------------------------------------------
|
||||
|
||||
const option_guide *datapack_device::create_option_guide() const
|
||||
const util::option_guide &datapack_device::create_option_guide() const
|
||||
{
|
||||
return datapack_option_guide;
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
virtual bool is_reset_on_load() const override { return 0; }
|
||||
virtual const char *image_interface() const override { return "psion_pack"; }
|
||||
virtual const char *file_extensions() const override { return "opk"; }
|
||||
virtual const option_guide *create_option_guide() const override;
|
||||
virtual const util::option_guide &create_option_guide() const override;
|
||||
|
||||
// specific implementation
|
||||
UINT8 data_r();
|
||||
|
@ -269,7 +269,7 @@ static void imgtool_floppy_get_info(const imgtool_class *imgclass, UINT32 state,
|
||||
case IMGTOOLINFO_PTR_OPEN: info->open = imgtool_floppy_open; break;
|
||||
case IMGTOOLINFO_PTR_CREATE: info->create = imgtool_floppy_create; break;
|
||||
case IMGTOOLINFO_PTR_CLOSE: info->close = imgtool_floppy_close; break;
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = format->param_guidelines ? floppy_option_guide : nullptr; break;
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = format->param_guidelines ? &floppy_option_guide : nullptr; break;
|
||||
case IMGTOOLINFO_PTR_GET_SECTOR_SIZE: info->get_sector_size = imgtool_floppy_get_sector_size; break;
|
||||
case IMGTOOLINFO_PTR_READ_SECTOR: info->read_sector = imgtool_floppy_read_sector; break;
|
||||
case IMGTOOLINFO_PTR_WRITE_SECTOR: info->write_sector = imgtool_floppy_write_sector; break;
|
||||
|
@ -226,7 +226,7 @@ enum
|
||||
mess_hd_createopts_seclen = 'F'
|
||||
};
|
||||
|
||||
static OPTION_GUIDE_START( mess_hd_create_optionguide )
|
||||
OPTION_GUIDE_START( mess_hd_create_optionguide )
|
||||
OPTION_INT(mess_hd_createopts_blocksize, "blocksize", "Sectors Per Block" )
|
||||
OPTION_INT(mess_hd_createopts_cylinders, "cylinders", "Cylinders" )
|
||||
OPTION_INT(mess_hd_createopts_heads, "heads", "Heads" )
|
||||
@ -247,7 +247,7 @@ void hd_get_info(const imgtool_class *imgclass, UINT32 state, union imgtoolinfo
|
||||
|
||||
case IMGTOOLINFO_PTR_CREATE: info->create = mess_hd_image_create; break;
|
||||
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = mess_hd_create_optionguide; break;
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = &mess_hd_create_optionguide; break;
|
||||
case IMGTOOLINFO_STR_CREATEIMAGE_OPTSPEC: strcpy(info->s = imgtool_temp_str(), mess_hd_create_optionspecs); break;
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
// copyright-holders:Nathan Woods
|
||||
/***************************************************************************
|
||||
|
||||
imgtool.c
|
||||
imgtool.cpp
|
||||
|
||||
Core code for Imgtool
|
||||
|
||||
@ -66,7 +66,7 @@ struct imgtool_partition
|
||||
imgtoolerr_t (*suggest_transfer)(imgtool_partition *partition, const char *path, imgtool_transfer_suggestion *suggestions, size_t suggestions_length);
|
||||
imgtoolerr_t (*get_chain) (imgtool_partition *partition, const char *path, imgtool_chainent *chain, size_t chain_size);
|
||||
|
||||
const option_guide *writefile_optguide;
|
||||
const util::option_guide *writefile_optguide;
|
||||
const char *writefile_optspec;
|
||||
};
|
||||
|
||||
@ -800,7 +800,7 @@ imgtoolerr_t imgtool_partition_open(imgtool_image *image, int partition_index, i
|
||||
p->get_iconinfo = (imgtoolerr_t (*)(imgtool_partition *, const char *, imgtool_iconinfo *)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_GET_ICON_INFO);
|
||||
p->suggest_transfer = (imgtoolerr_t (*)(imgtool_partition *, const char *, imgtool_transfer_suggestion *, size_t)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_SUGGEST_TRANSFER);
|
||||
p->get_chain = (imgtoolerr_t (*)(imgtool_partition *, const char *, imgtool_chainent *, size_t)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_GET_CHAIN);
|
||||
p->writefile_optguide = (const option_guide *) imgtool_get_info_ptr(&imgclass, IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE);
|
||||
p->writefile_optguide = (const util::option_guide *) imgtool_get_info_ptr(&imgclass, IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE);
|
||||
p->writefile_optspec = pool_strdup_allow_null(p->pool, (char*)imgtool_get_info_ptr(&imgclass, IMGTOOLINFO_STR_WRITEFILE_OPTSPEC));
|
||||
|
||||
/* mask out if writing is untested */
|
||||
@ -928,10 +928,8 @@ void imgtool_partition_get_attribute_name(imgtool_partition *partition, UINT32 a
|
||||
int imgtool_validitychecks(void)
|
||||
{
|
||||
int error = 0;
|
||||
int val;
|
||||
imgtoolerr_t err = (imgtoolerr_t)IMGTOOLERR_SUCCESS;
|
||||
const imgtool_module *module = nullptr;
|
||||
const option_guide *guide_entry;
|
||||
imgtool_module_features features;
|
||||
int created_library = FALSE;
|
||||
|
||||
@ -1017,44 +1015,12 @@ int imgtool_validitychecks(void)
|
||||
|
||||
if (module->createimage_optguide && module->createimage_optspec)
|
||||
{
|
||||
guide_entry = module->createimage_optguide;
|
||||
while (guide_entry->option_type != OPTIONTYPE_END)
|
||||
{
|
||||
if (util::option_resolution::contains(module->createimage_optspec, guide_entry->parameter))
|
||||
{
|
||||
switch (guide_entry->option_type)
|
||||
{
|
||||
case OPTIONTYPE_INT:
|
||||
case OPTIONTYPE_ENUM_BEGIN:
|
||||
err = (imgtoolerr_t)util::option_resolution::get_default(module->createimage_optspec,
|
||||
guide_entry->parameter, &val);
|
||||
if (err)
|
||||
goto done;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!guide_entry->identifier)
|
||||
{
|
||||
printf("imgtool module %s creation option %d has null identifier\n",
|
||||
module->name, (int) (guide_entry - module->createimage_optguide));
|
||||
error = 1;
|
||||
}
|
||||
if (!guide_entry->display_name)
|
||||
{
|
||||
printf("imgtool module %s creation option %d has null display_name\n",
|
||||
module->name, (int) (guide_entry - module->createimage_optguide));
|
||||
error = 1;
|
||||
}
|
||||
}
|
||||
guide_entry++;
|
||||
}
|
||||
auto resolution = std::make_unique<util::option_resolution>(*module->createimage_optguide);
|
||||
resolution->set_specification(module->createimage_optspec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (created_library)
|
||||
imgtool_exit();
|
||||
if (err)
|
||||
@ -1218,12 +1184,14 @@ imgtoolerr_t imgtool_image_create(const imgtool_module *module, const char *fnam
|
||||
/* allocate dummy options if necessary */
|
||||
if (!opts && module->createimage_optguide)
|
||||
{
|
||||
try { alloc_resolution.reset(new util::option_resolution(module->createimage_optguide, module->createimage_optspec)); }
|
||||
try { alloc_resolution.reset(new util::option_resolution(*module->createimage_optguide)); }
|
||||
catch (...) { return (imgtoolerr_t)IMGTOOLERR_OUTOFMEMORY; }
|
||||
|
||||
if (module->createimage_optspec)
|
||||
alloc_resolution->set_specification(module->createimage_optspec);
|
||||
|
||||
opts = alloc_resolution.get();
|
||||
}
|
||||
if (opts)
|
||||
opts->finish();
|
||||
|
||||
return internal_open(module, fname, OSD_FOPEN_RW_CREATE, opts, image);
|
||||
}
|
||||
@ -2000,16 +1968,16 @@ imgtoolerr_t imgtool_partition_write_file(imgtool_partition *partition, const ch
|
||||
/* allocate dummy options if necessary */
|
||||
if (!opts && partition->writefile_optguide)
|
||||
{
|
||||
try { alloc_resolution.reset(new util::option_resolution(partition->writefile_optguide, partition->writefile_optspec)); }
|
||||
try { alloc_resolution.reset(new util::option_resolution(*partition->writefile_optguide)); }
|
||||
catch (...)
|
||||
{
|
||||
err = IMGTOOLERR_OUTOFMEMORY;
|
||||
goto done;
|
||||
}
|
||||
if (partition->writefile_optspec)
|
||||
alloc_resolution->set_specification(partition->writefile_optspec);
|
||||
opts = alloc_resolution.get();
|
||||
}
|
||||
if (opts)
|
||||
opts->finish();
|
||||
|
||||
/* if free_space is implemented; do a quick check to see if space is available */
|
||||
if (partition->free_space)
|
||||
|
@ -102,7 +102,7 @@ static void imgtool_library_add_class(imgtool_library *library, const imgtool_cl
|
||||
module->write_block = (imgtoolerr_t (*)(imgtool_image *, const void *, UINT64)) imgtool_get_info_fct(imgclass, IMGTOOLINFO_PTR_WRITE_BLOCK);
|
||||
module->list_partitions = (imgtoolerr_t (*)(imgtool_image *, imgtool_partition_info *, size_t)) imgtool_get_info_fct(imgclass, IMGTOOLINFO_PTR_LIST_PARTITIONS);
|
||||
module->block_size = imgtool_get_info_int(imgclass, IMGTOOLINFO_INT_BLOCK_SIZE);
|
||||
module->createimage_optguide = (const option_guide *) imgtool_get_info_ptr(imgclass, IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE);
|
||||
module->createimage_optguide = (const util::option_guide *) imgtool_get_info_ptr(imgclass, IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE);
|
||||
module->createimage_optspec = imgtool_library_strdup_allow_null(library, (const char*)imgtool_get_info_ptr(imgclass, IMGTOOLINFO_STR_CREATEIMAGE_OPTSPEC));
|
||||
module->image_extra_bytes += imgtool_get_info_int(imgclass, IMGTOOLINFO_INT_IMAGE_EXTRA_BYTES);
|
||||
}
|
||||
|
@ -291,8 +291,8 @@ union imgtoolinfo
|
||||
int (*approve_filename_char)(unicode_char ch);
|
||||
int (*make_class)(int index, imgtool_class *imgclass);
|
||||
|
||||
const option_guide *createimage_optguide;
|
||||
const option_guide *writefile_optguide;
|
||||
const util::option_guide *createimage_optguide;
|
||||
const util::option_guide *writefile_optguide;
|
||||
};
|
||||
|
||||
|
||||
@ -369,7 +369,7 @@ struct imgtool_module
|
||||
|
||||
UINT32 block_size;
|
||||
|
||||
const option_guide *createimage_optguide;
|
||||
const util::option_guide *createimage_optguide;
|
||||
const char *createimage_optspec;
|
||||
|
||||
const void *extra;
|
||||
|
@ -2,7 +2,7 @@
|
||||
// copyright-holders:Nathan Woods
|
||||
/***************************************************************************
|
||||
|
||||
main.c
|
||||
main.cpp
|
||||
|
||||
Imgtool command line front end
|
||||
|
||||
@ -17,6 +17,8 @@
|
||||
#include "imgtool.h"
|
||||
#include "main.h"
|
||||
#include "modules.h"
|
||||
#include "strformat.h"
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static void writeusage(FILE *f, int write_word_usage, const struct command *c, char *argv[])
|
||||
@ -40,7 +42,6 @@ static int parse_options(int argc, char *argv[], int minunnamed, int maxunnamed,
|
||||
char *s;
|
||||
char *name = nullptr;
|
||||
char *value = nullptr;
|
||||
util::option_resolution::error oerr;
|
||||
static char buf[256];
|
||||
|
||||
if (filter)
|
||||
@ -97,9 +98,7 @@ static int parse_options(int argc, char *argv[], int minunnamed, int maxunnamed,
|
||||
if (i < minunnamed)
|
||||
goto error; /* Too few unnamed */
|
||||
|
||||
oerr = resolution->add_param(name, value);
|
||||
if (oerr != util::option_resolution::error::SUCCESS)
|
||||
goto opterror;
|
||||
resolution->find(name)->set_value(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -113,10 +112,6 @@ optionalreadyspecified:
|
||||
fprintf(stderr, "Cannot specify multiple %ss\n", name);
|
||||
return -1;
|
||||
|
||||
opterror:
|
||||
fprintf(stderr, "%s: %s\n", name, util::option_resolution::error_string(oerr));
|
||||
return -1;
|
||||
|
||||
error:
|
||||
fprintf(stderr, "%s: Unrecognized option\n", argv[i]);
|
||||
return -1;
|
||||
@ -328,7 +323,7 @@ static int cmd_put(const struct command *c, int argc, char *argv[])
|
||||
char **filename_list;
|
||||
int filename_count;
|
||||
int partition_index = 0;
|
||||
const option_guide *writefile_optguide;
|
||||
const util::option_guide *writefile_optguide;
|
||||
const char *writefile_optspec;
|
||||
|
||||
module = imgtool_find_module(argv[0]);
|
||||
@ -353,17 +348,18 @@ static int cmd_put(const struct command *c, int argc, char *argv[])
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
writefile_optguide = (const option_guide *) imgtool_partition_get_info_ptr(partition, IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE);
|
||||
writefile_optguide = (const util::option_guide *) imgtool_partition_get_info_ptr(partition, IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE);
|
||||
writefile_optspec = (const char *)imgtool_partition_get_info_ptr(partition, IMGTOOLINFO_STR_WRITEFILE_OPTSPEC);
|
||||
|
||||
if (writefile_optguide && writefile_optspec)
|
||||
{
|
||||
try { resolution.reset(new util::option_resolution(writefile_optguide, writefile_optspec)); }
|
||||
try { resolution.reset(new util::option_resolution(*writefile_optguide)); }
|
||||
catch (...)
|
||||
{
|
||||
err = IMGTOOLERR_OUTOFMEMORY;
|
||||
goto done;
|
||||
}
|
||||
resolution->set_specification(writefile_optspec);
|
||||
}
|
||||
}
|
||||
|
||||
@ -592,12 +588,13 @@ static int cmd_create(const struct command *c, int argc, char *argv[])
|
||||
|
||||
if (module->createimage_optguide && module->createimage_optspec)
|
||||
{
|
||||
try { resolution.reset(new util::option_resolution(module->createimage_optguide, module->createimage_optspec)); }
|
||||
try { resolution.reset(new util::option_resolution(*module->createimage_optguide)); }
|
||||
catch (...)
|
||||
{
|
||||
err = IMGTOOLERR_OUTOFMEMORY;
|
||||
goto error;
|
||||
}
|
||||
resolution->set_specification(module->createimage_optspec);
|
||||
}
|
||||
|
||||
unnamedargs = parse_options(argc, argv, 2, 3, resolution.get(), nullptr, nullptr);
|
||||
@ -742,77 +739,63 @@ static int cmd_listfilters(const struct command *c, int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void listoptions(const option_guide *opt_guide, const char *opt_spec)
|
||||
static void listoptions(const util::option_guide &opt_guide, const char *opt_spec)
|
||||
{
|
||||
char opt_name[32];
|
||||
const char *opt_desc;
|
||||
util::option_resolution::range range[32];
|
||||
char range_buffer[512];
|
||||
char buf[32];
|
||||
int i;
|
||||
|
||||
assert(opt_guide);
|
||||
util::option_resolution resolution(opt_guide);
|
||||
resolution.set_specification(opt_spec);
|
||||
|
||||
fprintf(stdout, "Option Allowed values Description\n");
|
||||
fprintf(stdout, "---------------- ------------------------------ -----------\n");
|
||||
|
||||
while(opt_guide->option_type != OPTIONTYPE_END)
|
||||
std::stringstream description_buffer;
|
||||
for (auto iter = resolution.entries_begin(); iter != resolution.entries_end(); iter++)
|
||||
{
|
||||
range_buffer[0] = 0;
|
||||
snprintf(opt_name, ARRAY_LENGTH(opt_name), "--%s", opt_guide->identifier);
|
||||
opt_desc = opt_guide->display_name;
|
||||
const util::option_resolution::entry &entry = *iter;
|
||||
|
||||
/* is this option relevant? */
|
||||
if (!strchr(opt_spec, opt_guide->parameter))
|
||||
{
|
||||
opt_guide++;
|
||||
std::string opt_name = string_format("--%s", entry.identifier());
|
||||
const char *opt_desc = entry.display_name();
|
||||
|
||||
// is this option relevant?
|
||||
if (!strchr(opt_spec, entry.parameter()))
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(opt_guide->option_type) {
|
||||
case OPTIONTYPE_INT:
|
||||
util::option_resolution::list_ranges(opt_spec, opt_guide->parameter,
|
||||
range, ARRAY_LENGTH(range));
|
||||
|
||||
for (i = 0; range[i].max >= 0; i++)
|
||||
switch (entry.option_type())
|
||||
{
|
||||
case util::option_guide::entry::option_type::INT:
|
||||
for (const auto &range : entry.ranges())
|
||||
{
|
||||
if (range[i].min == range[i].max)
|
||||
snprintf(buf, ARRAY_LENGTH(buf), "%i", range[i].min);
|
||||
if (!description_buffer.str().empty())
|
||||
description_buffer << "/";
|
||||
|
||||
if (range.min == range.max)
|
||||
util::stream_format(description_buffer, "%d", range.min);
|
||||
else
|
||||
snprintf(buf, ARRAY_LENGTH(buf), "%i-%i", range[i].min, range[i].max);
|
||||
|
||||
if (i > 0)
|
||||
strncatz(range_buffer, "/", sizeof(range_buffer));
|
||||
strncatz(range_buffer, buf, sizeof(range_buffer));
|
||||
util::stream_format(description_buffer, "%d-%d", range.min, range.max);
|
||||
}
|
||||
break;
|
||||
|
||||
case OPTIONTYPE_ENUM_BEGIN:
|
||||
i = 0;
|
||||
while(opt_guide[1].option_type == OPTIONTYPE_ENUM_VALUE)
|
||||
case util::option_guide::entry::option_type::ENUM_BEGIN:
|
||||
for (auto enum_value = entry.enum_value_begin(); enum_value != entry.enum_value_end(); enum_value++)
|
||||
{
|
||||
if (i > 0)
|
||||
strncatz(range_buffer, "/", sizeof(range_buffer));
|
||||
strncatz(range_buffer, opt_guide[1].identifier, sizeof(range_buffer));
|
||||
|
||||
opt_guide++;
|
||||
i++;
|
||||
if (!description_buffer.str().empty())
|
||||
description_buffer << '/';
|
||||
description_buffer << enum_value->identifier();
|
||||
}
|
||||
break;
|
||||
|
||||
case OPTIONTYPE_STRING:
|
||||
snprintf(range_buffer, sizeof(range_buffer), "(string)");
|
||||
case util::option_guide::entry::option_type::STRING:
|
||||
description_buffer << "(string)";
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stdout, "%16s %-30s %s\n",
|
||||
opt_name,
|
||||
range_buffer,
|
||||
opt_name.c_str(),
|
||||
description_buffer.str().c_str(),
|
||||
opt_desc);
|
||||
opt_guide++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -821,7 +804,7 @@ static void listoptions(const option_guide *opt_guide, const char *opt_spec)
|
||||
static int cmd_listdriveroptions(const struct command *c, int argc, char *argv[])
|
||||
{
|
||||
const imgtool_module *mod;
|
||||
const option_guide *opt_guide;
|
||||
const util::option_guide *opt_guide;
|
||||
const char *opt_spec;
|
||||
|
||||
mod = imgtool_find_module(argv[0]);
|
||||
@ -834,12 +817,12 @@ static int cmd_listdriveroptions(const struct command *c, int argc, char *argv[]
|
||||
fprintf(stdout, "Driver specific options for module '%s':\n\n", argv[0]);
|
||||
|
||||
/* list write options */
|
||||
opt_guide = (const option_guide *) imgtool_get_info_ptr(&mod->imgclass, IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE);
|
||||
opt_guide = (const util::option_guide *) imgtool_get_info_ptr(&mod->imgclass, IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE);
|
||||
opt_spec = imgtool_get_info_string(&mod->imgclass, IMGTOOLINFO_STR_WRITEFILE_OPTSPEC);
|
||||
if (opt_guide)
|
||||
{
|
||||
fprintf(stdout, "Image specific file options (usable on the 'put' command):\n\n");
|
||||
listoptions(opt_guide, opt_spec);
|
||||
listoptions(*opt_guide, opt_spec);
|
||||
puts("\n");
|
||||
}
|
||||
else
|
||||
@ -852,7 +835,7 @@ static int cmd_listdriveroptions(const struct command *c, int argc, char *argv[]
|
||||
if (opt_guide)
|
||||
{
|
||||
fprintf(stdout, "Image specific creation options (usable on the 'create' command):\n\n");
|
||||
listoptions(opt_guide, mod->createimage_optspec);
|
||||
listoptions(*opt_guide, mod->createimage_optspec);
|
||||
puts("\n");
|
||||
}
|
||||
else
|
||||
@ -940,7 +923,7 @@ int CLIB_DECL main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* Usage */
|
||||
fprintf(stderr, "imgtool - Generic image manipulation tool for use with MESS\n\n");
|
||||
fprintf(stderr, "imgtool - Generic image manipulation tool for use with MAME\n\n");
|
||||
for (i = 0; i < ARRAY_LENGTH(cmds); i++)
|
||||
{
|
||||
writeusage(stdout, (i == 0), &cmds[i], argv);
|
||||
|
@ -2193,7 +2193,7 @@ static imgtoolerr_t amiga_image_writefile(imgtool_partition *partition, const ch
|
||||
static imgtoolerr_t amiga_image_create(imgtool_image *img, imgtool_stream *stream, util::option_resolution *opts)
|
||||
{
|
||||
amiga_floppy *f = (amiga_floppy *) imgtool_image_extra_bytes(img);
|
||||
const char *dskname = opts->lookup_string('N');
|
||||
const std::string &dskname = opts->lookup_string('N');
|
||||
imgtoolerr_t ret;
|
||||
UINT8 buffer[BSIZE];
|
||||
root_block root;
|
||||
@ -2252,10 +2252,10 @@ static imgtoolerr_t amiga_image_create(imgtool_image *img, imgtool_stream *strea
|
||||
amiga_setup_time(now, &root.c);
|
||||
|
||||
/* volume name */
|
||||
if (dskname)
|
||||
if (!dskname.empty())
|
||||
{
|
||||
root.name_len = strlen(dskname);
|
||||
memcpy(&root.diskname, dskname, root.name_len);
|
||||
root.name_len = dskname.length();
|
||||
memcpy(&root.diskname, dskname.c_str(), root.name_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2342,7 +2342,7 @@ static imgtoolerr_t amiga_image_suggesttransfer(imgtool_partition *partition, co
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
static OPTION_GUIDE_START(amiga_createimage_optionguide)
|
||||
OPTION_GUIDE_START(amiga_createimage_optionguide)
|
||||
OPTION_STRING( 'N', "name", "Volume name" )
|
||||
OPTION_ENUM_START( 'S', "density", "Density" )
|
||||
OPTION_ENUM( 0, "dd", "Double Density" )
|
||||
@ -2406,6 +2406,6 @@ void amiga_floppy_get_info(const imgtool_class *imgclass, UINT32 state, union im
|
||||
case IMGTOOLINFO_PTR_SET_ATTRS: info->set_attrs = amiga_image_setattrs; break;
|
||||
case IMGTOOLINFO_PTR_GET_ICON_INFO: info->get_iconinfo = amiga_image_geticoninfo; break;
|
||||
case IMGTOOLINFO_PTR_SUGGEST_TRANSFER: info->suggest_transfer = amiga_image_suggesttransfer; break;
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = amiga_createimage_optionguide; break;
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = &amiga_createimage_optionguide; break;
|
||||
}
|
||||
}
|
||||
|
@ -882,7 +882,7 @@ static imgtoolerr_t bml3_diskimage_suggesttransfer(imgtool_partition *partition,
|
||||
Imgtool module declaration
|
||||
*********************************************************************/
|
||||
|
||||
static OPTION_GUIDE_START( bml3_writefile_optionguide )
|
||||
OPTION_GUIDE_START( bml3_writefile_optionguide )
|
||||
OPTION_ENUM_START( BML3_OPTIONS_FTYPE, "ftype", "File type" )
|
||||
OPTION_ENUM( 0, "basic", "Basic" )
|
||||
OPTION_ENUM( 1, "data", "Data" )
|
||||
@ -922,7 +922,7 @@ void bml3_get_info(const imgtool_class *imgclass, UINT32 state, union imgtoolinf
|
||||
case IMGTOOLINFO_PTR_WRITE_FILE: info->write_file = bml3_diskimage_writefile; break;
|
||||
case IMGTOOLINFO_PTR_DELETE_FILE: info->delete_file = bml3_diskimage_deletefile; break;
|
||||
case IMGTOOLINFO_PTR_SUGGEST_TRANSFER: info->suggest_transfer = bml3_diskimage_suggesttransfer; break;
|
||||
case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE: info->writefile_optguide = bml3_writefile_optionguide; break;
|
||||
case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE: info->writefile_optguide = &bml3_writefile_optionguide; break;
|
||||
case IMGTOOLINFO_PTR_FLOPPY_FORMAT: info->p = (void *) floppyoptions_default; break;
|
||||
}
|
||||
}
|
||||
|
@ -531,7 +531,7 @@ static imgtoolerr_t cybiko_image_delete_file( imgtool_partition *partition, cons
|
||||
return IMGTOOLERR_SUCCESS;
|
||||
}
|
||||
|
||||
static OPTION_GUIDE_START( cybiko_image_createimage_optguide )
|
||||
OPTION_GUIDE_START( cybiko_image_createimage_optguide )
|
||||
OPTION_ENUM_START( 'F', "flash", "Flash Type" )
|
||||
OPTION_ENUM( 0, "AT45DB041", "AT45DB041 (528 KByte)" )
|
||||
OPTION_ENUM( 1, "AT45DB081", "AT45DB081 (1056 KByte)" )
|
||||
@ -564,7 +564,7 @@ void cybiko_get_info( const imgtool_class *imgclass, UINT32 state, union imgtool
|
||||
case IMGTOOLINFO_PTR_READ_FILE : info->read_file = cybiko_image_read_file; break;
|
||||
case IMGTOOLINFO_PTR_WRITE_FILE : info->write_file = cybiko_image_write_file; break;
|
||||
case IMGTOOLINFO_PTR_DELETE_FILE : info->delete_file = cybiko_image_delete_file; break;
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE : info->createimage_optguide = cybiko_image_createimage_optguide; break;
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE : info->createimage_optguide = &cybiko_image_createimage_optguide; break;
|
||||
// case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE : info->writefile_optguide = cybiko_image_writefile_optguide; break;
|
||||
// --- the following bits of info are returned as NULL-terminated strings ---
|
||||
case IMGTOOLINFO_STR_NAME : strcpy( info->s = imgtool_temp_str(), "cybiko"); break;
|
||||
|
@ -136,7 +136,7 @@ static const char* hp48_prefix = "HPHP48-R";
|
||||
|
||||
|
||||
|
||||
static OPTION_GUIDE_START( hp48_create_optionguide )
|
||||
OPTION_GUIDE_START( hp48_create_optionguide )
|
||||
OPTION_INT('S', "size", "Size in KB" )
|
||||
OPTION_GUIDE_END
|
||||
|
||||
@ -726,7 +726,7 @@ void hp48_get_info(const imgtool_class *imgclass, UINT32 state, union imgtoolinf
|
||||
case IMGTOOLINFO_STR_FILE_EXTENSIONS: strcpy(info->s = imgtool_temp_str(), "crd"); break;
|
||||
case IMGTOOLINFO_STR_CREATEIMAGE_OPTSPEC: strcpy(info->s = imgtool_temp_str(), hp48_create_optionspec); break;
|
||||
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = hp48_create_optionguide; break;
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = &hp48_create_optionguide; break;
|
||||
|
||||
/* --- the following bits of info are returned as pointers to data or functions --- */
|
||||
case IMGTOOLINFO_PTR_OPEN: info->open = hp48_open; break;
|
||||
|
@ -55,7 +55,7 @@
|
||||
|
||||
#define FAT_SECLEN 512
|
||||
|
||||
static OPTION_GUIDE_START( pc_chd_create_optionguide )
|
||||
OPTION_GUIDE_START( pc_chd_create_optionguide )
|
||||
OPTION_INT('T', "cylinders", "Cylinders" )
|
||||
OPTION_INT('H', "heads", "Heads" )
|
||||
OPTION_INT('S', "sectors", "Sectors" )
|
||||
@ -463,7 +463,7 @@ void pc_chd_get_info(const imgtool_class *imgclass, UINT32 state, union imgtooli
|
||||
case IMGTOOLINFO_PTR_READ_BLOCK: info->read_block = pc_chd_image_readblock; break;
|
||||
case IMGTOOLINFO_PTR_WRITE_BLOCK: info->write_block = pc_chd_image_writeblock; break;
|
||||
case IMGTOOLINFO_PTR_GET_SECTOR_SIZE: info->get_sector_size = pc_chd_image_getsectorsize; break;
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = pc_chd_create_optionguide; break;
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = &pc_chd_create_optionguide; break;
|
||||
case IMGTOOLINFO_PTR_GET_GEOMETRY: info->get_geometry = pc_chd_image_get_geometry; break;
|
||||
case IMGTOOLINFO_PTR_LIST_PARTITIONS: info->list_partitions = pc_chd_list_partitions; break;
|
||||
}
|
||||
|
@ -626,7 +626,7 @@ static imgtoolerr_t datapack_delete_file( imgtool_partition *partition, const ch
|
||||
return IMGTOOLERR_FILENOTFOUND;
|
||||
}
|
||||
|
||||
static OPTION_GUIDE_START( psion_create_optguide )
|
||||
OPTION_GUIDE_START( psion_create_optguide )
|
||||
OPTION_ENUM_START( 'S', "size", "datapack size" )
|
||||
OPTION_ENUM( 1, "8k", "8 kbyte" )
|
||||
OPTION_ENUM( 2, "16k", "16 kbyts" )
|
||||
@ -641,7 +641,7 @@ static OPTION_GUIDE_START( psion_create_optguide )
|
||||
OPTION_INT('C', "copy", "copyable datapack" )
|
||||
OPTION_GUIDE_END
|
||||
|
||||
static OPTION_GUIDE_START( psion_write_optguide )
|
||||
OPTION_GUIDE_START( psion_write_optguide )
|
||||
OPTION_ENUM_START( 'T', "type", "file type" )
|
||||
OPTION_ENUM( 1, "OB3", "OB3 files" )
|
||||
OPTION_ENUM( 2, "OPL", "OPL files" )
|
||||
@ -669,8 +669,8 @@ void psion_get_info( const imgtool_class *imgclass, UINT32 state, union imgtooli
|
||||
case IMGTOOLINFO_PTR_READ_FILE : info->read_file = datapack_read_file; break;
|
||||
case IMGTOOLINFO_PTR_WRITE_FILE : info->write_file = datapack_write_file; break;
|
||||
case IMGTOOLINFO_PTR_DELETE_FILE : info->delete_file = datapack_delete_file; break;
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE : info->createimage_optguide = psion_create_optguide; break;
|
||||
case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE : info->createimage_optguide = psion_write_optguide; break;
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE : info->createimage_optguide = &psion_create_optguide; break;
|
||||
case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE : info->createimage_optguide = &psion_write_optguide; break;
|
||||
|
||||
// --- the following bits of info are returned as NULL-terminated strings ---
|
||||
case IMGTOOLINFO_STR_NAME : strcpy( info->s = imgtool_temp_str(), "psionpack"); break;
|
||||
|
@ -579,7 +579,7 @@ static imgtoolerr_t rsdos_diskimage_suggesttransfer(imgtool_partition *partition
|
||||
Imgtool module declaration
|
||||
*********************************************************************/
|
||||
|
||||
static OPTION_GUIDE_START( coco_rsdos_writefile_optionguide )
|
||||
OPTION_GUIDE_START( coco_rsdos_writefile_optionguide )
|
||||
OPTION_ENUM_START( RSDOS_OPTIONS_FTYPE, "ftype", "File type" )
|
||||
OPTION_ENUM( 0, "basic", "Basic" )
|
||||
OPTION_ENUM( 1, "data", "Data" )
|
||||
@ -617,7 +617,7 @@ void rsdos_get_info(const imgtool_class *imgclass, UINT32 state, union imgtoolin
|
||||
case IMGTOOLINFO_PTR_WRITE_FILE: info->write_file = rsdos_diskimage_writefile; break;
|
||||
case IMGTOOLINFO_PTR_DELETE_FILE: info->delete_file = rsdos_diskimage_deletefile; break;
|
||||
case IMGTOOLINFO_PTR_SUGGEST_TRANSFER: info->suggest_transfer = rsdos_diskimage_suggesttransfer; break;
|
||||
case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE: info->writefile_optguide = coco_rsdos_writefile_optionguide; break;
|
||||
case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE: info->writefile_optguide = &coco_rsdos_writefile_optionguide; break;
|
||||
case IMGTOOLINFO_PTR_FLOPPY_FORMAT: info->p = (void *) floppyoptions_coco; break;
|
||||
}
|
||||
}
|
||||
|
@ -1065,7 +1065,7 @@ static imgtoolerr_t thom_write_file(imgtool_partition *part,
|
||||
}
|
||||
|
||||
/* comment */
|
||||
char const *const comment = opts->lookup_string('C');
|
||||
char const *const comment = opts->lookup_string('C').c_str();
|
||||
if (comment && *comment)
|
||||
strncpy(d.comment, comment, 8);
|
||||
|
||||
@ -1132,7 +1132,7 @@ static imgtoolerr_t thom_create(imgtool_image* img,
|
||||
/* get parameters */
|
||||
f->heads = opts->lookup_int('H');
|
||||
f->tracks = opts->lookup_int('T');
|
||||
name = opts->lookup_string('N');
|
||||
name = opts->lookup_string('N').c_str();
|
||||
switch ( opts->lookup_int('D') ) {
|
||||
case 0: f->sector_size = 128; f->sectuse_size = 128; break;
|
||||
case 1: f->sector_size = 256; f->sectuse_size = 255; break;
|
||||
@ -1519,7 +1519,7 @@ FILTER( thombas128,
|
||||
|
||||
/************************* driver ***************************/
|
||||
|
||||
static OPTION_GUIDE_START( thom_createimage_optguide )
|
||||
OPTION_GUIDE_START( thom_createimage_optguide )
|
||||
OPTION_INT( 'H', "heads", "Heads" )
|
||||
OPTION_INT( 'T', "tracks", "Tracks" )
|
||||
OPTION_ENUM_START( 'D', "density", "Density" )
|
||||
@ -1529,7 +1529,7 @@ static OPTION_GUIDE_START( thom_createimage_optguide )
|
||||
OPTION_STRING( 'N', "name", "Floppy name" )
|
||||
OPTION_GUIDE_END
|
||||
|
||||
static OPTION_GUIDE_START( thom_writefile_optguide )
|
||||
OPTION_GUIDE_START( thom_writefile_optguide )
|
||||
OPTION_ENUM_START( 'T', "ftype", "File type" )
|
||||
OPTION_ENUM( 0, "auto", "Automatic (by extension)" )
|
||||
OPTION_ENUM( 1, "B", "Program" )
|
||||
@ -1571,7 +1571,7 @@ static void thom_basic_get_info(const imgtool_class *clas,
|
||||
case IMGTOOLINFO_PTR_CREATE:
|
||||
info->create = thom_create; break;
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE:
|
||||
info->createimage_optguide = thom_createimage_optguide; break;
|
||||
info->createimage_optguide = &thom_createimage_optguide; break;
|
||||
case IMGTOOLINFO_PTR_BEGIN_ENUM:
|
||||
info->begin_enum = thom_begin_enum; break;
|
||||
case IMGTOOLINFO_PTR_NEXT_ENUM:
|
||||
@ -1581,7 +1581,7 @@ static void thom_basic_get_info(const imgtool_class *clas,
|
||||
case IMGTOOLINFO_PTR_WRITE_FILE:
|
||||
info->write_file = thom_write_file; break;
|
||||
case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE:
|
||||
info->writefile_optguide = thom_writefile_optguide; break;
|
||||
info->writefile_optguide = &thom_writefile_optguide; break;
|
||||
case IMGTOOLINFO_STR_WRITEFILE_OPTSPEC:
|
||||
strcpy( info->s = imgtool_temp_str(), "T[0]-4;F[0]-2;C" ); break;
|
||||
case IMGTOOLINFO_PTR_SUGGEST_TRANSFER:
|
||||
|
@ -3877,7 +3877,7 @@ enum
|
||||
dsk_createopts_density = 'F'
|
||||
};
|
||||
|
||||
static OPTION_GUIDE_START( dsk_create_optionguide )
|
||||
OPTION_GUIDE_START( dsk_create_optionguide )
|
||||
OPTION_STRING(dsk_createopts_volname, "label", "Volume name" )
|
||||
OPTION_INT(dsk_createopts_sides, "sides", "Sides" )
|
||||
OPTION_INT(dsk_createopts_tracks, "tracks", "Tracks" )
|
||||
@ -3929,7 +3929,7 @@ void ti99_old_get_info(const imgtool_class *imgclass, UINT32 state, union imgtoo
|
||||
case IMGTOOLINFO_STR_DESCRIPTION: strcpy(info->s = imgtool_temp_str(), "TI99 Diskette (old MESS format)"); break;
|
||||
case IMGTOOLINFO_PTR_OPEN: info->open = dsk_image_init_mess; break;
|
||||
case IMGTOOLINFO_PTR_CREATE: info->create = dsk_image_create_mess; break;
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = dsk_create_optionguide; break;
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = &dsk_create_optionguide; break;
|
||||
case IMGTOOLINFO_STR_CREATEIMAGE_OPTSPEC: strcpy(info->s = imgtool_temp_str(), dsk_create_optionspecs); break;
|
||||
default: ti99_dsk_getinfo(imgclass, state, info); break;
|
||||
}
|
||||
@ -3943,7 +3943,7 @@ void ti99_v9t9_get_info(const imgtool_class *imgclass, UINT32 state, union imgto
|
||||
case IMGTOOLINFO_STR_DESCRIPTION: strcpy(info->s = imgtool_temp_str(), "TI99 Diskette (V9T9 format)"); break;
|
||||
case IMGTOOLINFO_PTR_OPEN: info->open = dsk_image_init_v9t9; break;
|
||||
case IMGTOOLINFO_PTR_CREATE: info->create = dsk_image_create_v9t9; break;
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = dsk_create_optionguide; break;
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = &dsk_create_optionguide; break;
|
||||
case IMGTOOLINFO_STR_CREATEIMAGE_OPTSPEC: strcpy(info->s = imgtool_temp_str(), dsk_create_optionspecs); break;
|
||||
default: ti99_dsk_getinfo(imgclass, state, info); break;
|
||||
}
|
||||
@ -5244,7 +5244,7 @@ static imgtoolerr_t dsk_image_create(imgtool_image *image, imgtool_stream *f, ut
|
||||
l1_img.file_handle = f;
|
||||
|
||||
/* read options */
|
||||
volname = createoptions->lookup_string(dsk_createopts_volname);
|
||||
volname = createoptions->lookup_string(dsk_createopts_volname).c_str();
|
||||
l1_img.geometry.heads = createoptions->lookup_int(dsk_createopts_sides);
|
||||
l1_img.geometry.cylinders = createoptions->lookup_int(dsk_createopts_tracks);
|
||||
l1_img.geometry.secspertrack = createoptions->lookup_int(dsk_createopts_sectors);
|
||||
|
@ -409,7 +409,7 @@ enum
|
||||
ti990_createopts_sectorsize = 'E'
|
||||
};
|
||||
|
||||
static OPTION_GUIDE_START( ti990_create_optionguide )
|
||||
OPTION_GUIDE_START( ti990_create_optionguide )
|
||||
/*OPTION_STRING(ti990_createopts_volname, "label", "Volume name" )*/
|
||||
OPTION_INT(ti990_createopts_cylinders, "cylinders", "Cylinders" )
|
||||
OPTION_INT(ti990_createopts_heads, "heads", "Heads" )
|
||||
@ -442,7 +442,7 @@ void ti990_get_info(const imgtool_class *imgclass, UINT32 state, union imgtoolin
|
||||
case IMGTOOLINFO_PTR_DELETE_FILE: /* info->delete_file = ti990_image_deletefile; */ break;
|
||||
case IMGTOOLINFO_PTR_CREATE: info->create = ti990_image_create; break;
|
||||
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = ti990_create_optionguide; break;
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = &ti990_create_optionguide; break;
|
||||
case IMGTOOLINFO_STR_CREATEIMAGE_OPTSPEC: strcpy(info->s = imgtool_temp_str(), ti990_create_optionspecs); break;
|
||||
}
|
||||
}
|
||||
|
@ -903,7 +903,7 @@ void filter_vzsnapshot_getinfo(UINT32 state, union filterinfo *info)
|
||||
Imgtool module declaration
|
||||
*********************************************************************/
|
||||
|
||||
static OPTION_GUIDE_START(vzdos_writefile_optionguide)
|
||||
OPTION_GUIDE_START(vzdos_writefile_optionguide)
|
||||
OPTION_ENUM_START( 'T', "ftype", "File type" )
|
||||
OPTION_ENUM( 0, "basic", "Basic" )
|
||||
OPTION_ENUM( 1, "binary", "Binary" )
|
||||
@ -953,7 +953,7 @@ void vzdos_get_info(const imgtool_class *imgclass, UINT32 state, union imgtoolin
|
||||
case IMGTOOLINFO_PTR_WRITE_FILE: info->write_file = vzdos_diskimage_writefile; break;
|
||||
case IMGTOOLINFO_PTR_DELETE_FILE: info->delete_file = vzdos_diskimage_deletefile; break;
|
||||
case IMGTOOLINFO_PTR_FLOPPY_CREATE: info->create = vzdos_diskimage_create; break;
|
||||
case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE: info->writefile_optguide = vzdos_writefile_optionguide; break;
|
||||
case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE: info->writefile_optguide = &vzdos_writefile_optionguide; break;
|
||||
case IMGTOOLINFO_PTR_SUGGEST_TRANSFER: info->suggest_transfer = vzdos_diskimage_suggesttransfer; break;
|
||||
case IMGTOOLINFO_PTR_FLOPPY_FORMAT: info->p = (void *) floppyoptions_vz; break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user