Merge pull request #1056 from npwoods/opresolv_cplusplusification

C++-ification of src/lib/util/opresolv.[cpp|h]
This commit is contained in:
Vas Crabb 2016-07-08 12:37:58 +10:00 committed by GitHub
commit 1c0947a717
25 changed files with 382 additions and 400 deletions

View File

@ -65,7 +65,7 @@ public:
virtual const char *file_extensions() const override { return "awd"; } virtual const char *file_extensions() const override { return "awd"; }
virtual const option_guide *create_option_guide() const override { return nullptr; } virtual const option_guide *create_option_guide() const override { return nullptr; }
virtual bool call_create(int format_type, option_resolution *format_options) override; virtual bool call_create(int format_type, util::option_resolution *format_options) override;
protected: protected:
// device-level overrides // device-level overrides
virtual void device_config_complete() override; virtual void device_config_complete() override;
@ -1406,7 +1406,7 @@ void omti_disk_image_device::device_reset()
disk image create callback disk image create callback
-------------------------------------------------*/ -------------------------------------------------*/
bool omti_disk_image_device::call_create(int format_type, option_resolution *format_options) bool omti_disk_image_device::call_create(int format_type, util::option_resolution *format_options)
{ {
LOG(("device_create_omti_disk: creating OMTI Disk with %d blocks", m_sector_count)); LOG(("device_create_omti_disk: creating OMTI Disk with %d blocks", m_sector_count));

View File

@ -88,7 +88,7 @@ bool bitbanger_device::call_load(void)
return IMAGE_INIT_PASS; return IMAGE_INIT_PASS;
} }
bool bitbanger_device::call_create(int format_type, option_resolution *format_options) bool bitbanger_device::call_create(int format_type, util::option_resolution *format_options)
{ {
/* we don't need to do anything special */ /* we don't need to do anything special */
return IMAGE_INIT_PASS; return IMAGE_INIT_PASS;

View File

@ -18,7 +18,7 @@ public:
// image-level overrides // image-level overrides
virtual bool call_load() override; virtual bool call_load() override;
virtual bool call_create(int format_type, option_resolution *format_options) override; virtual bool call_create(int format_type, util::option_resolution *format_options) override;
virtual void call_unload() override; virtual void call_unload() override;
// image device // image device

View File

@ -250,7 +250,7 @@ void cassette_image_device::device_start()
m_value = 0; m_value = 0;
} }
bool cassette_image_device::call_create(int format_type, option_resolution *format_options) bool cassette_image_device::call_create(int format_type, util::option_resolution *format_options)
{ {
return call_load(); return call_load();
} }

View File

@ -56,7 +56,7 @@ public:
// image-level overrides // image-level overrides
virtual bool call_load() override; virtual bool call_load() override;
virtual bool call_create(int format_type, option_resolution *format_options) override; virtual bool call_create(int format_type, util::option_resolution *format_options) override;
virtual void call_unload() override; virtual void call_unload() override;
virtual std::string call_display() override; virtual std::string call_display() override;
virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry) override { return load_software(swlist, swname, start_entry); } virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry) override { return load_software(swlist, swname, start_entry); }

View File

@ -108,17 +108,18 @@ bool diablo_image_device::call_load()
} }
bool diablo_image_device::call_create(int create_format, option_resolution *create_args) bool diablo_image_device::call_create(int create_format, util::option_resolution *create_args)
{ {
int err; int err;
UINT32 sectorsize, hunksize; UINT32 sectorsize, hunksize;
UINT32 cylinders, heads, sectors, totalsectors; UINT32 cylinders, heads, sectors, totalsectors;
cylinders = option_resolution_lookup_int(create_args, 'C'); assert_always(create_args != nullptr, "Expected create_args to not be nullptr");
heads = option_resolution_lookup_int(create_args, 'H'); cylinders = create_args->lookup_int('C');
sectors = option_resolution_lookup_int(create_args, 'S'); heads = create_args->lookup_int('H');
sectorsize = option_resolution_lookup_int(create_args, 'L') * sizeof(UINT16); sectors = create_args->lookup_int('S');
hunksize = option_resolution_lookup_int(create_args, 'K'); sectorsize = create_args->lookup_int('L') * sizeof(UINT16);
hunksize = create_args->lookup_int('K');
totalsectors = cylinders * heads * sectors; totalsectors = cylinders * heads * sectors;

View File

@ -31,7 +31,7 @@ public:
// image-level overrides // image-level overrides
virtual bool call_load() override; virtual bool call_load() override;
virtual bool call_create(int create_format, option_resolution *create_args) override; virtual bool call_create(int create_format, util::option_resolution *create_args) override;
virtual void call_unload() override; virtual void call_unload() override;
virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry) override { device().machine().rom_load().load_software_part_region(*this, swlist, swname, start_entry ); return TRUE; } virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry) override { device().machine().rom_load().load_software_part_region(*this, swlist, swname, start_entry ); return TRUE; }

View File

@ -417,7 +417,7 @@ void legacy_floppy_image_device::floppy_drive_set_controller(device_t *controlle
m_controller = controller; m_controller = controller;
} }
int legacy_floppy_image_device::internal_floppy_device_load(int create_format, option_resolution *create_args) int legacy_floppy_image_device::internal_floppy_device_load(int create_format, util::option_resolution *create_args)
{ {
floperr_t err; floperr_t err;
const struct FloppyFormat *floppy_options; const struct FloppyFormat *floppy_options;
@ -830,7 +830,7 @@ void legacy_floppy_image_device::device_config_complete()
update_names(); update_names();
} }
bool legacy_floppy_image_device::call_create(int format_type, option_resolution *format_options) bool legacy_floppy_image_device::call_create(int format_type, util::option_resolution *format_options)
{ {
return internal_floppy_device_load(format_type, format_options); return internal_floppy_device_load(format_type, format_options);
} }

View File

@ -101,7 +101,7 @@ public:
virtual bool call_load() override; virtual bool call_load() override;
virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry) override { return load_software(swlist, swname, start_entry); } virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry) override { return load_software(swlist, swname, start_entry); }
virtual bool call_create(int format_type, option_resolution *format_options) override; virtual bool call_create(int format_type, util::option_resolution *format_options) override;
virtual void call_unload() override; virtual void call_unload() override;
virtual iodevice_t image_type() const override { return IO_FLOPPY; } virtual iodevice_t image_type() const override { return IO_FLOPPY; }
@ -162,7 +162,7 @@ private:
TIMER_CALLBACK_MEMBER(floppy_drive_index_callback); TIMER_CALLBACK_MEMBER(floppy_drive_index_callback);
void floppy_drive_init(); void floppy_drive_init();
void floppy_drive_index_func(); void floppy_drive_index_func();
int internal_floppy_device_load(int create_format, option_resolution *create_args); int internal_floppy_device_load(int create_format, util::option_resolution *create_args);
TIMER_CALLBACK_MEMBER( set_wpt ); TIMER_CALLBACK_MEMBER( set_wpt );
protected: protected:

View File

@ -479,7 +479,7 @@ void floppy_image_device::call_unload()
} }
} }
bool floppy_image_device::call_create(int format_type, option_resolution *format_options) bool floppy_image_device::call_create(int format_type, util::option_resolution *format_options)
{ {
image = global_alloc(floppy_image(tracks, sides, form_factor)); image = global_alloc(floppy_image(tracks, sides, form_factor));
output_format = nullptr; output_format = nullptr;

View File

@ -82,7 +82,7 @@ public:
// image-level overrides // image-level overrides
virtual bool call_load() override; virtual bool call_load() override;
virtual void call_unload() override; virtual void call_unload() override;
virtual bool call_create(int format_type, option_resolution *format_options) override; virtual bool call_create(int format_type, util::option_resolution *format_options) override;
virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry) override { return load_software(swlist, swname, start_entry); } virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry) override { return load_software(swlist, swname, start_entry); }
virtual const char *image_interface() const override = 0; virtual const char *image_interface() const override = 0;
virtual iodevice_t image_type() const override { return IO_FLOPPY; } virtual iodevice_t image_type() const override { return IO_FLOPPY; }

View File

@ -132,17 +132,18 @@ bool harddisk_image_device::call_load()
} }
bool harddisk_image_device::call_create(int create_format, option_resolution *create_args) bool harddisk_image_device::call_create(int create_format, util::option_resolution *create_args)
{ {
int err; int err;
UINT32 sectorsize, hunksize; UINT32 sectorsize, hunksize;
UINT32 cylinders, heads, sectors, totalsectors; UINT32 cylinders, heads, sectors, totalsectors;
cylinders = option_resolution_lookup_int(create_args, 'C'); assert_always(create_args != nullptr, "Expected create_args to not be nullptr");
heads = option_resolution_lookup_int(create_args, 'H'); cylinders = create_args->lookup_int('C');
sectors = option_resolution_lookup_int(create_args, 'S'); heads = create_args->lookup_int('H');
sectorsize = option_resolution_lookup_int(create_args, 'L'); sectors = create_args->lookup_int('S');
hunksize = option_resolution_lookup_int(create_args, 'K'); sectorsize = create_args->lookup_int('L');
hunksize = create_args->lookup_int('K');
totalsectors = cylinders * heads * sectors; totalsectors = cylinders * heads * sectors;

View File

@ -33,7 +33,7 @@ public:
// image-level overrides // image-level overrides
virtual bool call_load() override; virtual bool call_load() override;
virtual bool call_create(int create_format, option_resolution *create_args) override; virtual bool call_create(int create_format, util::option_resolution *create_args) override;
virtual void call_unload() override; virtual void call_unload() override;
virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry) override { machine().rom_load().load_software_part_region(*this, swlist, swname, start_entry ); return TRUE; } virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry) override { machine().rom_load().load_software_part_region(*this, swlist, swname, start_entry ); return TRUE; }

View File

@ -80,7 +80,7 @@ void printer_image_device::output(UINT8 data)
DEVICE_IMAGE_CREATE( printer ) DEVICE_IMAGE_CREATE( printer )
-------------------------------------------------*/ -------------------------------------------------*/
bool printer_image_device::call_create(int format_type, option_resolution *format_options) bool printer_image_device::call_create(int format_type, util::option_resolution *format_options)
{ {
return call_load(); return call_load();
} }

View File

@ -31,7 +31,7 @@ public:
// image-level overrides // image-level overrides
virtual bool call_load() override; virtual bool call_load() override;
virtual bool call_create(int format_type, option_resolution *format_options) override; virtual bool call_create(int format_type, util::option_resolution *format_options) override;
virtual void call_unload() override; virtual void call_unload() override;
// image device // image device

View File

@ -933,7 +933,7 @@ bool device_image_interface::load_software(software_list_device &swlist, const c
// load_internal - core image loading // load_internal - core image loading
//------------------------------------------------- //-------------------------------------------------
bool device_image_interface::load_internal(const char *path, bool is_create, int create_format, option_resolution *create_args, bool just_load) bool device_image_interface::load_internal(const char *path, bool is_create, int create_format, util::option_resolution *create_args, bool just_load)
{ {
UINT32 open_plan[4]; UINT32 open_plan[4];
int i; int i;
@ -1143,7 +1143,7 @@ bool device_image_interface::finish_load()
// create - create a image // create - create a image
//------------------------------------------------- //-------------------------------------------------
bool device_image_interface::create(const char *path, const image_device_format *create_format, option_resolution *create_args) bool device_image_interface::create(const char *path, const image_device_format *create_format, util::option_resolution *create_args)
{ {
int format_index = 0; int format_index = 0;
int cnt = 0; int cnt = 0;

View File

@ -144,7 +144,7 @@ public:
virtual bool call_load() { return FALSE; } virtual bool call_load() { return FALSE; }
virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry) { return FALSE; } virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry) { return FALSE; }
virtual bool call_create(int format_type, option_resolution *format_options) { return FALSE; } virtual bool call_create(int format_type, util::option_resolution *format_options) { return FALSE; }
virtual void call_unload() { } virtual void call_unload() { }
virtual std::string call_display() { return std::string(); } virtual std::string call_display() { return std::string(); }
virtual device_image_partialhash_func get_partial_hash() const { return nullptr; } virtual device_image_partialhash_func get_partial_hash() const { return nullptr; }
@ -226,7 +226,7 @@ public:
bool open_image_file(emu_options &options); bool open_image_file(emu_options &options);
bool finish_load(); bool finish_load();
void unload(); void unload();
bool create(const char *path, const image_device_format *create_format, option_resolution *create_args); bool create(const char *path, const image_device_format *create_format, util::option_resolution *create_args);
bool load_software(software_list_device &swlist, const char *swname, const rom_entry *entry); bool load_software(software_list_device &swlist, const char *swname, const rom_entry *entry);
int reopen_for_write(const char *path); int reopen_for_write(const char *path);
@ -242,7 +242,7 @@ public:
bool user_loadable() const { return m_user_loadable; } bool user_loadable() const { return m_user_loadable; }
protected: protected:
bool load_internal(const char *path, bool is_create, int create_format, option_resolution *create_args, bool just_load); bool load_internal(const char *path, bool is_create, int create_format, util::option_resolution *create_args, bool just_load);
void determine_open_plan(int is_create, UINT32 *open_plan); void determine_open_plan(int is_create, UINT32 *open_plan);
image_error_t load_image_by_path(UINT32 open_flags, const char *path); image_error_t load_image_by_path(UINT32 open_flags, const char *path);
void clear(); void clear();
@ -306,7 +306,7 @@ protected:
/* special - used when creating */ /* special - used when creating */
int m_create_format; int m_create_format;
option_resolution *m_create_args; util::option_resolution *m_create_args;
hash_collection m_hash; hash_collection m_hash;

View File

@ -862,7 +862,7 @@ static FLOPPY_CONSTRUCT(apple35_raw_construct)
if (params) if (params)
{ {
/* create */ /* create */
sides = option_resolution_lookup_int(params, PARAM_HEADS); sides = params->lookup_int(PARAM_HEADS);
size = 80*sides*10*512; size = 80*sides*10*512;
is_1440k = FALSE; is_1440k = FALSE;
} }
@ -995,7 +995,7 @@ static FLOPPY_CONSTRUCT(apple35_diskcopy_construct)
if (params) if (params)
{ {
/* create */ /* create */
sides = option_resolution_lookup_int(params, PARAM_HEADS); sides = params->lookup_int(PARAM_HEADS);
data_size = 80*sides*10*512; data_size = 80*sides*10*512;
tag_size = 80*sides*10*12; tag_size = 80*sides*10*12;
@ -1139,7 +1139,7 @@ static FLOPPY_CONSTRUCT(apple35_2img_construct)
if (params) if (params)
{ {
/* create */ /* create */
sides = option_resolution_lookup_int(params, PARAM_HEADS); sides = params->lookup_int(PARAM_HEADS);
data_offset = sizeof(header); data_offset = sizeof(header);
data_size = 80*sides*10*512; data_size = 80*sides*10*512;

View File

@ -22,7 +22,7 @@ static floperr_t basicdsk_get_sector_length(floppy_image_legacy *floppy, int hea
static floperr_t basicdsk_get_indexed_sector_info(floppy_image_legacy *floppy, int head, int track, int sector_index, int *cylinder, int *side, int *sector, UINT32 *sector_length, unsigned long *flags); static floperr_t basicdsk_get_indexed_sector_info(floppy_image_legacy *floppy, int head, int track, int sector_index, int *cylinder, int *side, int *sector, UINT32 *sector_length, unsigned long *flags);
static int basicdsk_get_heads_per_disk(floppy_image_legacy *floppy); static int basicdsk_get_heads_per_disk(floppy_image_legacy *floppy);
static int basicdsk_get_tracks_per_disk(floppy_image_legacy *floppy); static int basicdsk_get_tracks_per_disk(floppy_image_legacy *floppy);
static floperr_t basicdsk_format_track(floppy_image_legacy *floppy, int head, int track, option_resolution *params); static floperr_t basicdsk_format_track(floppy_image_legacy *floppy, int head, int track, util::option_resolution *params);
@ -180,7 +180,7 @@ static floperr_t basicdsk_write_indexed_sector(floppy_image_legacy *floppy, int
static floperr_t basicdsk_format_track(floppy_image_legacy *floppy, int head, int track, option_resolution *params) static floperr_t basicdsk_format_track(floppy_image_legacy *floppy, int head, int track, util::option_resolution *params)
{ {
floperr_t err = FLOPPY_ERROR_SUCCESS; floperr_t err = FLOPPY_ERROR_SUCCESS;
UINT8 local_buffer[512]; UINT8 local_buffer[512];
@ -288,24 +288,23 @@ static floperr_t basicdsk_get_indexed_sector_info(floppy_image_legacy *floppy, i
static void basicdsk_default_geometry(const struct FloppyFormat *format, struct basicdsk_geometry *geometry) static void basicdsk_default_geometry(const struct FloppyFormat *format, struct basicdsk_geometry *geometry)
{ {
optreserr_t err;
int sector_length; int sector_length;
memset(geometry, 0, sizeof(*geometry)); memset(geometry, 0, sizeof(*geometry));
err = option_resolution_getdefault(format->param_guidelines, PARAM_HEADS, &geometry->heads); auto err = util::option_resolution::get_default(format->param_guidelines, PARAM_HEADS, &geometry->heads);
assert(!err); assert(err == util::option_resolution::error::SUCCESS);
err = option_resolution_getdefault(format->param_guidelines, PARAM_TRACKS, &geometry->tracks); err = util::option_resolution::get_default(format->param_guidelines, PARAM_TRACKS, &geometry->tracks);
assert(!err); assert(err == util::option_resolution::error::SUCCESS);
err = option_resolution_getdefault(format->param_guidelines, PARAM_SECTORS, &geometry->sectors); err = util::option_resolution::get_default(format->param_guidelines, PARAM_SECTORS, &geometry->sectors);
assert(!err); assert(err == util::option_resolution::error::SUCCESS);
err = option_resolution_getdefault(format->param_guidelines, PARAM_FIRST_SECTOR_ID, &geometry->first_sector_id); err = util::option_resolution::get_default(format->param_guidelines, PARAM_FIRST_SECTOR_ID, &geometry->first_sector_id);
assert(!err); assert(err == util::option_resolution::error::SUCCESS);
err = option_resolution_getdefault(format->param_guidelines, PARAM_INTERLEAVE, &geometry->interleave); err = util::option_resolution::get_default(format->param_guidelines, PARAM_INTERLEAVE, &geometry->interleave);
if (err!=0) { if (err != util::option_resolution::error::SUCCESS) {
geometry->interleave = 1; geometry->interleave = 1;
} }
err = option_resolution_getdefault(format->param_guidelines, PARAM_SECTOR_LENGTH, &sector_length); err = util::option_resolution::get_default(format->param_guidelines, PARAM_SECTOR_LENGTH, &sector_length);
assert(!err); assert(err == util::option_resolution::error::SUCCESS);
geometry->sector_length = sector_length; geometry->sector_length = sector_length;
if (geometry->interleave > 1) if (geometry->interleave > 1)

View File

@ -204,22 +204,22 @@ floperr_t floppy_open_choices(void *fp, const struct io_procs *procs, const char
static floperr_t option_to_floppy_error(optreserr_t oerr) static floperr_t option_to_floppy_error(util::option_resolution::error oerr)
{ {
floperr_t err; floperr_t err;
switch(oerr) { switch(oerr) {
case OPTIONRESOLUTION_ERROR_SUCCESS: case util::option_resolution::error::SUCCESS:
err = FLOPPY_ERROR_SUCCESS; err = FLOPPY_ERROR_SUCCESS;
break; break;
case OPTIONRESOLUTION_ERROR_OUTOFMEMORY: case util::option_resolution::error::OUTOFMEMORY:
err = FLOPPY_ERROR_OUTOFMEMORY; err = FLOPPY_ERROR_OUTOFMEMORY;
break; break;
case OPTIONRESOLUTION_ERROR_PARAMOUTOFRANGE: case util::option_resolution::error::PARAMOUTOFRANGE:
case OPTIONRESOLUTION_ERROR_PARAMNOTSPECIFIED: case util::option_resolution::error::PARAMNOTSPECIFIED:
case OPTIONRESOLUTION_ERROR_PARAMNOTFOUND: case util::option_resolution::error::PARAMNOTFOUND:
case OPTIONRESOLUTION_ERROR_PARAMALREADYSPECIFIED: case util::option_resolution::error::PARAMALREADYSPECIFIED:
case OPTIONRESOLUTION_ERROR_BADPARAM: case util::option_resolution::error::BADPARAM:
case OPTIONRESOLUTION_ERROR_SYNTAX: case util::option_resolution::error::SYNTAX:
default: default:
err = FLOPPY_ERROR_INTERNAL; err = FLOPPY_ERROR_INTERNAL;
break; break;
@ -229,13 +229,13 @@ static floperr_t option_to_floppy_error(optreserr_t oerr)
floperr_t floppy_create(void *fp, const struct io_procs *procs, const struct FloppyFormat *format, 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;
optreserr_t oerr; util::option_resolution::error oerr;
floperr_t err; floperr_t err;
int heads, tracks, h, t; int heads, tracks, h, t;
option_resolution *alloc_resolution = nullptr; std::unique_ptr<util::option_resolution> alloc_resolution;
assert(format); assert(format);
@ -250,20 +250,20 @@ 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 = option_resolution_create(floppy_option_guide, format->param_guidelines); alloc_resolution = std::make_unique<util::option_resolution>(floppy_option_guide, format->param_guidelines);
if (!alloc_resolution) if (!alloc_resolution)
{ {
err = FLOPPY_ERROR_OUTOFMEMORY; err = FLOPPY_ERROR_OUTOFMEMORY;
goto done; goto done;
} }
parameters = alloc_resolution; parameters = alloc_resolution.get();
} }
/* finish the parameters, if specified */ /* finish the parameters, if specified */
if (parameters) if (parameters)
{ {
oerr = option_resolution_finish(parameters); oerr = parameters->finish();
if (oerr) if (oerr != util::option_resolution::error::SUCCESS)
{ {
err = option_to_floppy_error(oerr); err = option_to_floppy_error(oerr);
goto done; goto done;
@ -314,9 +314,6 @@ done:
*outfloppy = floppy; *outfloppy = floppy;
else if (floppy) else if (floppy)
floppy_close_internal(floppy, FALSE); floppy_close_internal(floppy, FALSE);
if (alloc_resolution)
option_resolution_close(alloc_resolution);
return err; return err;
} }
@ -679,48 +676,36 @@ floperr_t floppy_write_track_data(floppy_image_legacy *floppy, int head, int tra
floperr_t floppy_format_track(floppy_image_legacy *floppy, int head, int track, option_resolution *parameters) floperr_t floppy_format_track(floppy_image_legacy *floppy, int head, int track, util::option_resolution *parameters)
{ {
floperr_t err; floperr_t err;
struct FloppyCallbacks *format; struct FloppyCallbacks *format;
option_resolution *alloc_resolution = nullptr; std::unique_ptr<util::option_resolution> alloc_resolution;
optreserr_t oerr;
/* supported? */ /* supported? */
format = floppy_callbacks(floppy); format = floppy_callbacks(floppy);
if (!format->format_track) if (!format->format_track)
{ return FLOPPY_ERROR_UNSUPPORTED;
err = FLOPPY_ERROR_UNSUPPORTED;
goto done;
}
/* create a dummy resolution; if no parameters were specified */ /* create a dummy resolution; if no parameters were specified */
if (!parameters) if (!parameters)
{ {
alloc_resolution = option_resolution_create(floppy_option_guide, floppy->floppy_option->param_guidelines); alloc_resolution = std::make_unique<util::option_resolution>(floppy_option_guide, floppy->floppy_option->param_guidelines);
if (!alloc_resolution) if (!alloc_resolution)
{ return FLOPPY_ERROR_OUTOFMEMORY;
err = FLOPPY_ERROR_OUTOFMEMORY;
goto done; parameters = alloc_resolution.get();
}
parameters = alloc_resolution;
} }
oerr = option_resolution_finish(parameters); auto oerr = parameters->finish();
if (oerr) if (oerr != util::option_resolution::error::SUCCESS)
{ return option_to_floppy_error(oerr);
err = option_to_floppy_error(oerr);
goto done;
}
err = format->format_track(floppy, head, track, parameters); err = format->format_track(floppy, head, track, parameters);
if (err) if (err)
goto done; return err;
done: return FLOPPY_ERROR_SUCCESS;
if (alloc_resolution)
option_resolution_close(alloc_resolution);
return err;
} }

View File

@ -68,8 +68,8 @@ struct FloppyCallbacks
floperr_t (*write_indexed_sector)(floppy_image_legacy *floppy, int head, int track, int sector_index, const void *buffer, size_t buflen, int ddam); floperr_t (*write_indexed_sector)(floppy_image_legacy *floppy, int head, int track, int sector_index, const void *buffer, size_t buflen, int ddam);
floperr_t (*read_track)(floppy_image_legacy *floppy, int head, int track, UINT64 offset, void *buffer, size_t buflen); floperr_t (*read_track)(floppy_image_legacy *floppy, int head, int track, UINT64 offset, void *buffer, size_t buflen);
floperr_t (*write_track)(floppy_image_legacy *floppy, int head, int track, UINT64 offset, const void *buffer, size_t buflen); floperr_t (*write_track)(floppy_image_legacy *floppy, int head, int track, UINT64 offset, const void *buffer, size_t buflen);
floperr_t (*format_track)(floppy_image_legacy *floppy, int head, int track, option_resolution *params); floperr_t (*format_track)(floppy_image_legacy *floppy, int head, int track, util::option_resolution *params);
floperr_t (*post_format)(floppy_image_legacy *floppy, option_resolution *params); floperr_t (*post_format)(floppy_image_legacy *floppy, util::option_resolution *params);
int (*get_heads_per_disk)(floppy_image_legacy *floppy); int (*get_heads_per_disk)(floppy_image_legacy *floppy);
int (*get_tracks_per_disk)(floppy_image_legacy *floppy); int (*get_tracks_per_disk)(floppy_image_legacy *floppy);
int (*get_sectors_per_track)(floppy_image_legacy *floppy, int head, int track); int (*get_sectors_per_track)(floppy_image_legacy *floppy, int head, int track);
@ -87,13 +87,13 @@ struct FloppyFormat
const char *extensions; const char *extensions;
const char *description; const char *description;
floperr_t (*identify)(floppy_image_legacy *floppy, const struct FloppyFormat *format, int *vote); floperr_t (*identify)(floppy_image_legacy *floppy, const struct FloppyFormat *format, int *vote);
floperr_t (*construct)(floppy_image_legacy *floppy, const struct FloppyFormat *format, option_resolution *params); floperr_t (*construct)(floppy_image_legacy *floppy, const struct FloppyFormat *format, util::option_resolution *params);
floperr_t (*destruct)(floppy_image_legacy *floppy, const struct FloppyFormat *format); floperr_t (*destruct)(floppy_image_legacy *floppy, const struct FloppyFormat *format);
const char *param_guidelines; const char *param_guidelines;
}; };
#define FLOPPY_IDENTIFY(name) floperr_t name(floppy_image_legacy *floppy, const struct FloppyFormat *format, int *vote) #define FLOPPY_IDENTIFY(name) floperr_t name(floppy_image_legacy *floppy, const struct FloppyFormat *format, int *vote)
#define FLOPPY_CONSTRUCT(name) floperr_t name(floppy_image_legacy *floppy, const struct FloppyFormat *format, option_resolution *params) #define FLOPPY_CONSTRUCT(name) floperr_t name(floppy_image_legacy *floppy, const struct FloppyFormat *format, util::option_resolution *params)
#define FLOPPY_DESTRUCT(name) floperr_t name(floppy_image_legacy *floppy, const struct FloppyFormat *format) #define FLOPPY_DESTRUCT(name) floperr_t name(floppy_image_legacy *floppy, const struct FloppyFormat *format)
FLOPPY_IDENTIFY(td0_dsk_identify); FLOPPY_IDENTIFY(td0_dsk_identify);
@ -166,7 +166,7 @@ OPTION_GUIDE_EXTERN(floppy_option_guide);
/* opening, closing and creating of floppy images */ /* opening, closing and creating of floppy images */
floperr_t floppy_open(void *fp, const struct io_procs *procs, const char *extension, const struct FloppyFormat *format, int flags, floppy_image_legacy **outfloppy); floperr_t floppy_open(void *fp, const struct io_procs *procs, const char *extension, const struct FloppyFormat *format, int flags, floppy_image_legacy **outfloppy);
floperr_t floppy_open_choices(void *fp, const struct io_procs *procs, const char *extension, const struct FloppyFormat *formats, int flags, floppy_image_legacy **outfloppy); floperr_t floppy_open_choices(void *fp, const struct io_procs *procs, const char *extension, const struct FloppyFormat *formats, int flags, floppy_image_legacy **outfloppy);
floperr_t floppy_create(void *fp, const struct io_procs *procs, const struct FloppyFormat *format, 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);
void floppy_close(floppy_image_legacy *floppy); void floppy_close(floppy_image_legacy *floppy);
/* useful for identifying a floppy image */ /* useful for identifying a floppy image */
@ -189,7 +189,7 @@ floperr_t floppy_read_track(floppy_image_legacy *floppy, int head, int track, vo
floperr_t floppy_write_track(floppy_image_legacy *floppy, int head, int track, const void *buffer, size_t buffer_len); floperr_t floppy_write_track(floppy_image_legacy *floppy, int head, int track, const void *buffer, size_t buffer_len);
floperr_t floppy_read_track_data(floppy_image_legacy *floppy, int head, int track, void *buffer, size_t buffer_len); floperr_t floppy_read_track_data(floppy_image_legacy *floppy, int head, int track, void *buffer, size_t buffer_len);
floperr_t floppy_write_track_data(floppy_image_legacy *floppy, int head, int track, const void *buffer, size_t buffer_len); floperr_t floppy_write_track_data(floppy_image_legacy *floppy, int head, int track, const void *buffer, size_t buffer_len);
floperr_t floppy_format_track(floppy_image_legacy *floppy, int head, int track, option_resolution *params); floperr_t floppy_format_track(floppy_image_legacy *floppy, int head, int track, util::option_resolution *params);
int floppy_get_tracks_per_disk(floppy_image_legacy *floppy); int floppy_get_tracks_per_disk(floppy_image_legacy *floppy);
int floppy_get_heads_per_disk(floppy_image_legacy *floppy); int floppy_get_heads_per_disk(floppy_image_legacy *floppy);
UINT32 floppy_get_track_size(floppy_image_legacy *floppy, int head, int track); UINT32 floppy_get_track_size(floppy_image_legacy *floppy, int head, int track);

View File

@ -112,9 +112,9 @@ static FLOPPY_CONSTRUCT(pc_dsk_construct)
{ {
/* create */ /* create */
memset(&geometry, 0, sizeof(geometry)); memset(&geometry, 0, sizeof(geometry));
geometry.heads = option_resolution_lookup_int(params, PARAM_HEADS); geometry.heads = params->lookup_int(PARAM_HEADS);
geometry.tracks = option_resolution_lookup_int(params, PARAM_TRACKS); geometry.tracks = params->lookup_int(PARAM_TRACKS);
geometry.sectors = option_resolution_lookup_int(params, PARAM_SECTORS); geometry.sectors = params->lookup_int(PARAM_SECTORS);
geometry.first_sector_id = 1; geometry.first_sector_id = 1;
geometry.sector_length = 512; geometry.sector_length = 512;
} }

View File

@ -210,7 +210,7 @@ static floperr_t sap_get_indexed_sector_info(floppy_image_legacy *floppy, int he
return err; return err;
} }
static floperr_t sap_post_format(floppy_image_legacy *floppy, option_resolution *params) static floperr_t sap_post_format(floppy_image_legacy *floppy, util::option_resolution *params)
{ {
int track,sector; int track,sector;
int pos; int pos;

View File

@ -17,33 +17,39 @@
#include "corestr.h" #include "corestr.h"
#include "opresolv.h" #include "opresolv.h"
enum resolution_entry_state
{
RESOLUTION_ENTRY_STATE_UNSPECIFIED,
RESOLUTION_ENTRY_STATE_SPECIFIED
};
struct option_resolution_entry namespace util {
{
const option_guide *guide_entry;
enum resolution_entry_state state;
union
{
int int_value;
const char *str_value;
} u;
};
struct option_resolution /***************************************************************************
{ option_resolution
object_pool *pool; ***************************************************************************/
const char *specification;
size_t option_count;
struct option_resolution_entry *entries;
};
static optreserr_t resolve_single_param(const char *specification, int *param_value, // -------------------------------------------------
struct OptionRange *range, size_t range_count) // entry::int_value
// -------------------------------------------------
int option_resolution::entry::int_value() const
{
return atoi(value.c_str());
}
// -------------------------------------------------
// entry::set_int_value
// -------------------------------------------------
void option_resolution::entry::set_int_value(int i)
{
value = string_format("%d", i);
}
// -------------------------------------------------
// resolve_single_param
// -------------------------------------------------
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_RANGE = 0x01;
int FLAG_IN_DEFAULT = 0x02; int FLAG_IN_DEFAULT = 0x02;
@ -62,7 +68,7 @@ static optreserr_t resolve_single_param(const char *specification, int *param_va
/* range specifier */ /* range specifier */
if (flags & (FLAG_IN_RANGE|FLAG_IN_DEFAULT)) if (flags & (FLAG_IN_RANGE|FLAG_IN_DEFAULT))
{ {
return OPTIONRESOLUTION_ERROR_SYNTAX; return error::SYNTAX;
} }
flags |= FLAG_IN_RANGE; flags |= FLAG_IN_RANGE;
s++; s++;
@ -82,7 +88,7 @@ static optreserr_t resolve_single_param(const char *specification, int *param_va
/* begin default value */ /* begin default value */
if (flags & (FLAG_IN_DEFAULT|FLAG_DEFAULT_SPECIFIED)) if (flags & (FLAG_IN_DEFAULT|FLAG_DEFAULT_SPECIFIED))
{ {
return OPTIONRESOLUTION_ERROR_SYNTAX; return error::SYNTAX;
} }
flags |= FLAG_IN_DEFAULT; flags |= FLAG_IN_DEFAULT;
s++; s++;
@ -92,21 +98,21 @@ static optreserr_t resolve_single_param(const char *specification, int *param_va
/* end default value */ /* end default value */
if ((flags & FLAG_IN_DEFAULT) == 0) if ((flags & FLAG_IN_DEFAULT) == 0)
{ {
return OPTIONRESOLUTION_ERROR_SYNTAX; return error::SYNTAX;
} }
flags &= ~FLAG_IN_DEFAULT; flags &= ~FLAG_IN_DEFAULT;
flags |= FLAG_DEFAULT_SPECIFIED; flags |= FLAG_DEFAULT_SPECIFIED;
s++; s++;
if (param_value && *param_value == -1) if (param_value && param_value->int_value() == -1)
*param_value = value; param_value->set_int_value(value);
} }
else if (*s == '/') else if (*s == '/')
{ {
/* value separator */ /* value separator */
if (flags & (FLAG_IN_DEFAULT|FLAG_IN_RANGE)) if (flags & (FLAG_IN_DEFAULT|FLAG_IN_RANGE))
{ {
return OPTIONRESOLUTION_ERROR_SYNTAX; return error::SYNTAX;
} }
s++; s++;
@ -147,35 +153,38 @@ static optreserr_t resolve_single_param(const char *specification, int *param_va
range->max = value; range->max = value;
} }
/* if we have a value; check to see if it is out of range */ // if we have a value; check to see if it is out of range
if (param_value && (*param_value != -1) && (*param_value != value)) if (param_value && (param_value->int_value() != -1) && (param_value->int_value() != value))
{ {
if ((last_value < *param_value) && (*param_value < value)) if ((last_value < param_value->int_value()) && (param_value->int_value() < value))
{ {
if ((flags & FLAG_IN_RANGE) == 0) if ((flags & FLAG_IN_RANGE) == 0)
return OPTIONRESOLUTION_ERROR_PARAMOUTOFRANGE; return error::PARAMOUTOFRANGE;
} }
} }
flags &= ~FLAG_IN_RANGE; flags &= ~FLAG_IN_RANGE;
} }
else else
{ {
return OPTIONRESOLUTION_ERROR_SYNTAX; return error::SYNTAX;
} }
} }
/* we can't have zero length guidelines strings */ // we can't have zero length guidelines strings
if (s == specification) if (s == specification)
{ {
return OPTIONRESOLUTION_ERROR_SYNTAX; return error::SYNTAX;
} }
return OPTIONRESOLUTION_ERROR_SUCCESS; return error::SUCCESS;
} }
// -------------------------------------------------
// lookup_in_specification
// -------------------------------------------------
static const char *lookup_in_specification(const char *specification, const option_guide *option) const char *option_resolution::lookup_in_specification(const char *specification, const option_guide *option)
{ {
const char *s; const char *s;
s = strchr(specification, option->parameter); s = strchr(specification, option->parameter);
@ -183,222 +192,191 @@ static const char *lookup_in_specification(const char *specification, const opti
} }
// -------------------------------------------------
// ctor
// -------------------------------------------------
option_resolution *option_resolution_create(const option_guide *guide, const char *specification) option_resolution::option_resolution(const option_guide *guide, const char *specification)
{ {
option_resolution *resolution = nullptr;
const option_guide *guide_entry; const option_guide *guide_entry;
int option_count; int option_count;
int opt = -1; int opt = -1;
object_pool *pool;
assert(guide); assert(guide);
/* first count the number of options specified in the guide */ // first count the number of options specified in the guide
option_count = option_resolution_countoptions(guide, specification); option_count = count_options(guide, specification);
/* create a memory pool for this structure */ // set up the entries list
pool = pool_alloc_lib(nullptr); m_specification = specification;
if (!pool) m_entries.resize(option_count);
goto outofmemory;
/* allocate the main structure */ // initialize each of the entries
resolution = (option_resolution *)pool_malloc_lib(pool, sizeof(option_resolution));
if (!resolution)
goto outofmemory;
memset(resolution, 0, sizeof(*resolution));
resolution->pool = pool;
/* set up the entries list */
resolution->option_count = option_count;
resolution->specification = specification;
resolution->entries = (option_resolution_entry *)pool_malloc_lib(resolution->pool, sizeof(struct option_resolution_entry) * option_count);
if (!resolution->entries)
goto outofmemory;
memset(resolution->entries, 0, sizeof(struct option_resolution_entry) * option_count);
/* initialize each of the entries */
opt = 0; opt = 0;
guide_entry = guide; guide_entry = guide;
while(guide_entry->option_type != OPTIONTYPE_END) while(guide_entry->option_type != OPTIONTYPE_END)
{ {
switch(guide_entry->option_type) { switch(guide_entry->option_type)
{
case OPTIONTYPE_INT: case OPTIONTYPE_INT:
case OPTIONTYPE_ENUM_BEGIN: case OPTIONTYPE_ENUM_BEGIN:
case OPTIONTYPE_STRING: case OPTIONTYPE_STRING:
if (lookup_in_specification(specification, guide_entry)) if (lookup_in_specification(specification, guide_entry))
resolution->entries[opt++].guide_entry = guide_entry; m_entries[opt++].guide_entry = guide_entry;
break; break;
case OPTIONTYPE_ENUM_VALUE: case OPTIONTYPE_ENUM_VALUE:
break; break;
default: default:
goto unexpected; assert(false && "Invalid option type");
break;
} }
guide_entry++; guide_entry++;
} }
assert(opt == option_count); assert(opt == option_count);
return resolution;
unexpected:
assert(FALSE);
outofmemory:
if (resolution)
option_resolution_close(resolution);
return nullptr;
} }
// -------------------------------------------------
// dtor
// -------------------------------------------------
optreserr_t option_resolution_add_param(option_resolution *resolution, const char *param, const char *value) option_resolution::~option_resolution()
{
}
// -------------------------------------------------
// add_param
// -------------------------------------------------
option_resolution::error option_resolution::add_param(const char *param, const std::string &value)
{ {
int i; int i;
int must_resolve; bool must_resolve;
optreserr_t err; error err;
const char *option_specification; const char *option_specification;
struct option_resolution_entry *entry = nullptr; entry *entry = nullptr;
for (i = 0; i < resolution->option_count; i++) for(auto &this_entry : m_entries)
{ {
if (!strcmp(param, resolution->entries[i].guide_entry->identifier)) if (!strcmp(param, this_entry.guide_entry->identifier))
{ {
entry = &resolution->entries[i]; entry = &this_entry;
break; break;
} }
} }
if (!entry) if (entry == nullptr)
return OPTIONRESOLUTION_ERROR_PARAMNOTFOUND; return error::PARAMNOTFOUND;
if (entry->state != RESOLUTION_ENTRY_STATE_UNSPECIFIED) if (entry->state != entry_state::UNSPECIFIED)
return OPTIONRESOLUTION_ERROR_PARAMALREADYSPECIFIED; return error::PARAMALREADYSPECIFIED;
switch(entry->guide_entry->option_type) { switch(entry->guide_entry->option_type) {
case OPTIONTYPE_INT: case OPTIONTYPE_INT:
entry->u.int_value = atoi(value); entry->set_int_value(atoi(value.c_str()));
entry->state = RESOLUTION_ENTRY_STATE_SPECIFIED; entry->state = entry_state::SPECIFIED;
must_resolve = TRUE; must_resolve = true;
break; break;
case OPTIONTYPE_STRING: case OPTIONTYPE_STRING:
entry->u.str_value = pool_strdup_lib(resolution->pool, value); entry->value = value;
if (!entry->u.str_value) entry->state = entry_state::SPECIFIED;
{ must_resolve = false;
err = OPTIONRESOLUTION_ERROR_OUTOFMEMORY;
goto done;
}
entry->state = RESOLUTION_ENTRY_STATE_SPECIFIED;
must_resolve = FALSE;
break; break;
case OPTIONTYPE_ENUM_BEGIN: case OPTIONTYPE_ENUM_BEGIN:
for (i = 1; entry->guide_entry[i].option_type == OPTIONTYPE_ENUM_VALUE; i++) for (i = 1; entry->guide_entry[i].option_type == OPTIONTYPE_ENUM_VALUE; i++)
{ {
if (!core_stricmp(value, entry->guide_entry[i].identifier)) if (!core_stricmp(value.c_str(), entry->guide_entry[i].identifier))
{ {
entry->u.int_value = entry->guide_entry[i].parameter; entry->set_int_value(entry->guide_entry[i].parameter);
entry->state = RESOLUTION_ENTRY_STATE_SPECIFIED; entry->state = entry_state::SPECIFIED;
break; break;
} }
} }
if (entry->state != RESOLUTION_ENTRY_STATE_SPECIFIED) if (entry->state != entry_state::SPECIFIED)
{ return error::BADPARAM;
err = OPTIONRESOLUTION_ERROR_BADPARAM;
goto done; must_resolve = true;
}
must_resolve = TRUE;
break; break;
default: default:
err = OPTIONRESOLTUION_ERROR_INTERNAL;
assert(0); assert(0);
goto done; return error::INTERNAL;
} }
/* do a resolution step if necessary */ // do a resolution step if necessary
if (must_resolve) if (must_resolve)
{ {
option_specification = lookup_in_specification(resolution->specification, entry->guide_entry); option_specification = lookup_in_specification(m_specification, entry->guide_entry);
err = resolve_single_param(option_specification, &entry->u.int_value, nullptr, 0); err = resolve_single_param(option_specification, entry, nullptr, 0);
if (err) if (err != error::SUCCESS)
goto done; return err;
/* did we not get a real value? */ // did we not get a real value?
if (entry->u.int_value < 0) if (entry->int_value() < 0)
{ return error::PARAMNOTSPECIFIED;
err = OPTIONRESOLUTION_ERROR_PARAMNOTSPECIFIED;
goto done;
}
} }
err = OPTIONRESOLUTION_ERROR_SUCCESS; return error::SUCCESS;
done:
return err;
} }
// -------------------------------------------------
// finish
// -------------------------------------------------
void option_resolution_close(option_resolution *resolution) option_resolution::error option_resolution::finish()
{ {
pool_free_lib(resolution->pool);
}
optreserr_t option_resolution_finish(option_resolution *resolution)
{
int i;
optreserr_t err;
struct option_resolution_entry *entry;
const char *option_specification; const char *option_specification;
error err;
for (i = 0; i < resolution->option_count; i++) for (auto &entry : m_entries)
{ {
entry = &resolution->entries[i]; if (entry.state == entry_state::UNSPECIFIED)
if (entry->state == RESOLUTION_ENTRY_STATE_UNSPECIFIED)
{ {
switch(entry->guide_entry->option_type) { switch(entry.guide_entry->option_type) {
case OPTIONTYPE_INT: case OPTIONTYPE_INT:
case OPTIONTYPE_ENUM_BEGIN: case OPTIONTYPE_ENUM_BEGIN:
option_specification = lookup_in_specification(resolution->specification, entry->guide_entry); option_specification = lookup_in_specification(m_specification, entry.guide_entry);
assert(option_specification); assert(option_specification);
entry->u.int_value = -1; entry.set_int_value(-1);
err = resolve_single_param(option_specification, &entry->u.int_value, nullptr, 0); err = resolve_single_param(option_specification, &entry, nullptr, 0);
if (err) if (err != error::SUCCESS)
return err; return err;
break; break;
case OPTIONTYPE_STRING: case OPTIONTYPE_STRING:
entry->u.str_value = ""; entry.value = "";
break; break;
default: default:
assert(FALSE); assert(FALSE);
return OPTIONRESOLTUION_ERROR_INTERNAL; return error::INTERNAL;
} }
entry->state = RESOLUTION_ENTRY_STATE_SPECIFIED; entry.state = entry_state::SPECIFIED;
} }
} }
return OPTIONRESOLUTION_ERROR_SUCCESS; return error::SUCCESS;
} }
// -------------------------------------------------
// lookup_entry
// -------------------------------------------------
static const struct option_resolution_entry *option_resolution_lookup_entry(option_resolution *resolution, int option_char) const option_resolution::entry *option_resolution::lookup_entry(int option_char) const
{ {
size_t i; for (auto &entry : m_entries)
const struct option_resolution_entry *entry;
for (i = 0; i < resolution->option_count; i++)
{ {
entry = &resolution->entries[i]; switch(entry.guide_entry->option_type) {
switch(entry->guide_entry->option_type) {
case OPTIONTYPE_INT: case OPTIONTYPE_INT:
case OPTIONTYPE_STRING: case OPTIONTYPE_STRING:
case OPTIONTYPE_ENUM_BEGIN: case OPTIONTYPE_ENUM_BEGIN:
if (entry->guide_entry->parameter == option_char) if (entry.guide_entry->parameter == option_char)
return entry; return &entry;
break; break;
default: default:
@ -410,53 +388,58 @@ static const struct option_resolution_entry *option_resolution_lookup_entry(opti
} }
// -------------------------------------------------
// lookup_int
// -------------------------------------------------
int option_resolution_lookup_int(option_resolution *resolution, int option_char) int option_resolution::lookup_int(int option_char) const
{ {
const struct option_resolution_entry *entry; auto entry = lookup_entry(option_char);
entry = option_resolution_lookup_entry(resolution, option_char); return entry ? entry->int_value() : -1;
return entry ? entry->u.int_value : -1;
} }
// -------------------------------------------------
// lookup_string
// -------------------------------------------------
const char *option_resolution_lookup_string(option_resolution *resolution, int option_char) const char *option_resolution::lookup_string(int option_char) const
{ {
const struct option_resolution_entry *entry; auto entry = lookup_entry(option_char);
entry = option_resolution_lookup_entry(resolution, option_char); return entry ? entry->value.c_str() : nullptr;
return entry ? entry->u.str_value : nullptr;
} }
// -------------------------------------------------
// find_option
// -------------------------------------------------
const char *option_resolution_specification(option_resolution *resolution) const option_guide *option_resolution::find_option(int option_char) const
{ {
return resolution->specification; auto entry = lookup_entry(option_char);
}
const option_guide *option_resolution_find_option(option_resolution *resolution, int option_char)
{
const struct option_resolution_entry *entry;
entry = option_resolution_lookup_entry(resolution, option_char);
return entry ? entry->guide_entry : nullptr; return entry ? entry->guide_entry : nullptr;
} }
// -------------------------------------------------
// index_option
// -------------------------------------------------
const option_guide *option_resolution_index_option(option_resolution *resolution, int indx) const option_guide *option_resolution::index_option(int indx) const
{ {
if ((indx < 0) || (indx >= resolution->option_count)) if ((indx < 0) || (indx >= m_entries.size()))
return nullptr; return nullptr;
return resolution->entries[indx].guide_entry; return m_entries[indx].guide_entry;
} }
// -------------------------------------------------
// count_options
// -------------------------------------------------
int option_resolution_countoptions(const option_guide *guide, const char *specification) size_t option_resolution::count_options(const option_guide *guide, const char *specification)
{ {
int option_count = 0; size_t option_count = 0;
while(guide->option_type != OPTIONTYPE_END) while(guide->option_type != OPTIONTYPE_END)
{ {
@ -479,105 +462,104 @@ int option_resolution_countoptions(const option_guide *guide, const char *specif
} }
// -------------------------------------------------
// list_ranges
// -------------------------------------------------
optreserr_t option_resolution_listranges(const char *specification, int option_char, option_resolution::error option_resolution::list_ranges(const char *specification, int option_char, range *range, size_t range_count)
struct OptionRange *range, size_t range_count)
{ {
assert(range_count > 0); assert(range_count > 0);
/* clear out range */ // clear out range
memset(range, -1, sizeof(*range) * range_count); memset(range, -1, sizeof(*range) * range_count);
range_count--; range_count--;
specification = strchr(specification, option_char); specification = strchr(specification, option_char);
if (!specification) if (!specification)
{ {
return OPTIONRESOLUTION_ERROR_SYNTAX; return error::SYNTAX;
} }
return resolve_single_param(specification + 1, nullptr, range, range_count); return resolve_single_param(specification + 1, nullptr, range, range_count);
} }
// -------------------------------------------------
// get_default
// -------------------------------------------------
optreserr_t option_resolution_getdefault(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); assert(val);
/* clear out default */ // clear out default
*val = -1; *val = -1;
specification = strchr(specification, option_char); specification = strchr(specification, option_char);
if (!specification) if (!specification)
{ {
return OPTIONRESOLUTION_ERROR_SYNTAX; return error::SYNTAX;
} }
return resolve_single_param(specification + 1, val, nullptr, 0); entry ent;
auto err = resolve_single_param(specification + 1, &ent, nullptr, 0);
*val = ent.int_value();
return err;
} }
// -------------------------------------------------
// list_ranges
// -------------------------------------------------
optreserr_t option_resolution_isvalidvalue(const char *specification, int option_char, int val) option_resolution::error option_resolution::is_valid_value(const char *specification, int option_char, int val)
{ {
optreserr_t err; option_resolution::error err;
struct OptionRange ranges[256]; range ranges[256];
int i; int i;
err = option_resolution_listranges(specification, option_char, ranges, ARRAY_LENGTH(ranges)); err = list_ranges(specification, option_char, ranges, ARRAY_LENGTH(ranges));
if (err) if (err != error::SUCCESS)
return err; return err;
for (i = 0; (ranges[i].min >= 0) && (ranges[i].max >= 0); i++) for (i = 0; (ranges[i].min >= 0) && (ranges[i].max >= 0); i++)
{ {
if ((ranges[i].min <= val) && (ranges[i].max >= val)) if ((ranges[i].min <= val) && (ranges[i].max >= val))
return OPTIONRESOLUTION_ERROR_SUCCESS; return error::SUCCESS;
} }
return OPTIONRESOLUTION_ERROR_PARAMOUTOFRANGE; return error::PARAMOUTOFRANGE;
} }
/**
* @fn int option_resolution_contains(const char *specification, int option_char)
*
* @brief Option resolution contains.
*
* @param specification The specification.
* @param option_char The option character.
*
* @return An int.
*/
int option_resolution_contains(const char *specification, int option_char) // -------------------------------------------------
// contains
// -------------------------------------------------
bool option_resolution::contains(const char *specification, int option_char)
{ {
return strchr(specification, option_char) != nullptr; return strchr(specification, option_char) != nullptr;
} }
/**
* @fn const char *option_resolution_error_string(optreserr_t err)
*
* @brief Option resolution error string.
*
* @param err The error.
*
* @return null if it fails, else a char*.
*/
const char *option_resolution_error_string(optreserr_t err) // -------------------------------------------------
// error_string
// -------------------------------------------------
const char *option_resolution::error_string(option_resolution::error err)
{ {
static const char *const errors[] = switch (err)
{ {
"The operation completed successfully", /* OPTIONRESOLUTION_ERROR_SUCCESS */ case error::SUCCESS: return "The operation completed successfully";
"Out of memory", /* OPTIONRESOLUTION_ERROR_OUTOFMEMORY */ case error::OUTOFMEMORY: return "Out of memory";
"Parameter out of range", /* OPTIONRESOLUTION_ERROR_PARAMOUTOFRANGE */ case error::PARAMOUTOFRANGE: return "Parameter out of range";
"Parameter not specified", /* OPTIONRESOLUTION_ERROR_PARAMNOTSPECIFIED */ case error::PARAMNOTSPECIFIED: return "Parameter not specified";
"Unknown parameter", /* OPTIONRESOLUTION_ERROR_PARAMNOTFOUND */ case error::PARAMNOTFOUND: return "Unknown parameter";
"Parameter specified multiple times", /* OPTIONRESOLUTION_ERROR_PARAMALREADYSPECIFIED */ case error::PARAMALREADYSPECIFIED: return "Parameter specified multiple times";
"Invalid parameter", /* OPTIONRESOLUTION_ERROR_BADPARAM */ case error::BADPARAM: return "Invalid parameter";
"Syntax error", /* OPTIONRESOLUTION_ERROR_SYNTAX */ case error::SYNTAX: return "Syntax error";
"Internal error" /* OPTIONRESOLTUION_ERROR_INTERNAL */ case error::INTERNAL: return "Internal error";
}; }
return nullptr;
if ((err < 0) || (err >= ARRAY_LENGTH(errors)))
return nullptr;
return errors[err];
} }
} // namespace util

View File

@ -42,13 +42,13 @@
#define __OPRESOLV_H__ #define __OPRESOLV_H__
#include <stdlib.h> #include <stdlib.h>
#include <vector>
#include <string>
/*************************************************************************** //**************************************************************************
// TYPE DEFINITIONS
Type definitions //**************************************************************************
***************************************************************************/
enum option_type enum option_type
{ {
@ -85,69 +85,83 @@ struct option_guide
{ OPTIONTYPE_ENUM_VALUE, (value), (identifier), (display_name) }, { OPTIONTYPE_ENUM_VALUE, (value), (identifier), (display_name) },
#define OPTION_ENUM_END #define OPTION_ENUM_END
namespace util {
enum optreserr_t class option_resolution
{ {
OPTIONRESOLUTION_ERROR_SUCCESS, public:
OPTIONRESOLUTION_ERROR_OUTOFMEMORY, enum class error
OPTIONRESOLUTION_ERROR_PARAMOUTOFRANGE, {
OPTIONRESOLUTION_ERROR_PARAMNOTSPECIFIED, SUCCESS,
OPTIONRESOLUTION_ERROR_PARAMNOTFOUND, OUTOFMEMORY,
OPTIONRESOLUTION_ERROR_PARAMALREADYSPECIFIED, PARAMOUTOFRANGE,
OPTIONRESOLUTION_ERROR_BADPARAM, PARAMNOTSPECIFIED,
OPTIONRESOLUTION_ERROR_SYNTAX, PARAMNOTFOUND,
OPTIONRESOLTUION_ERROR_INTERNAL PARAMALREADYSPECIFIED,
BADPARAM,
SYNTAX,
INTERNAL
};
struct range
{
int min, max;
};
option_resolution(const option_guide *guide, const char *specification);
~option_resolution();
// processing options with option_resolution objects
error add_param(const char *param, const std::string &value);
error finish();
int lookup_int(int option_char) const;
const char *lookup_string(int option_char) const;
// 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);
// misc
static const char *error_string(error err);
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);
const entry *lookup_entry(int option_char) const;
}; };
} // namespace util
struct OptionResolutionError
{
const option_guide *option;
optreserr_t error;
};
struct option_resolution;
struct OptionRange
{
int min, max;
};
/***************************************************************************
Prototypes
***************************************************************************/
/* processing options with option_resolution objects */
option_resolution *option_resolution_create(const option_guide *guide, const char *specification);
optreserr_t option_resolution_add_param(option_resolution *resolution, const char *param, const char *value);
optreserr_t option_resolution_finish(option_resolution *resolution);
void option_resolution_close(option_resolution *resolution);
int option_resolution_lookup_int(option_resolution *resolution, int option_char);
const char *option_resolution_lookup_string(option_resolution *resolution, int option_char);
/* option resolution accessors */
const char *option_resolution_specification(option_resolution *resolution);
const option_guide *option_resolution_find_option(option_resolution *resolution, int option_char);
const option_guide *option_resolution_index_option(option_resolution *resolution, int indx);
/* processing option guides */
int option_resolution_countoptions(const option_guide *guide, const char *specification);
/* processing option specifications */
optreserr_t option_resolution_listranges(const char *specification, int option_char,
struct OptionRange *range, size_t range_count);
optreserr_t option_resolution_getdefault(const char *specification, int option_char, int *val);
optreserr_t option_resolution_isvalidvalue(const char *specification, int option_char, int val);
int option_resolution_contains(const char *specification, int option_char);
/* misc */
const char *option_resolution_error_string(optreserr_t err);
#endif /* __OPRESOLV_H__ */ #endif /* __OPRESOLV_H__ */