diff options
author | 2017-03-29 13:01:38 +1100 | |
---|---|---|
committer | 2017-03-29 13:01:38 +1100 | |
commit | b690b27aa12ec4c598245fb023c85f1479db2c0f (patch) | |
tree | af428ce33a514feadfd606e0a52330f1c1d9cd0c /docs/release/src/emu/validity.cpp | |
parent | 05ca273f411d8def9f20e0e0305bf522af630e82 (diff) |
0.184 Release filestag184
Diffstat (limited to 'docs/release/src/emu/validity.cpp')
-rw-r--r-- | docs/release/src/emu/validity.cpp | 140 |
1 files changed, 130 insertions, 10 deletions
diff --git a/docs/release/src/emu/validity.cpp b/docs/release/src/emu/validity.cpp index d0007311a76..9fef85821ca 100644 --- a/docs/release/src/emu/validity.cpp +++ b/docs/release/src/emu/validity.cpp @@ -15,6 +15,9 @@ #include "video/rgbutil.h" #include <ctype.h> +#include <type_traits> +#include <typeindex> +#include <typeinfo> //************************************************************************** @@ -126,15 +129,15 @@ void validity_checker::validate_tag(const char *tag) //------------------------------------------------- validity_checker::validity_checker(emu_options &options) - : m_drivlist(options), - m_errors(0), - m_warnings(0), - m_print_verbose(options.verbose()), - m_current_driver(nullptr), - m_current_config(nullptr), - m_current_device(nullptr), - m_current_ioport(nullptr), - m_validate_all(false) + : m_drivlist(options) + , m_errors(0) + , m_warnings(0) + , m_print_verbose(options.verbose()) + , m_current_driver(nullptr) + , m_current_config(nullptr) + , m_current_device(nullptr) + , m_current_ioport(nullptr) + , m_validate_all(false) { // pre-populate the defstr map with all the default strings for (int strnum = 1; strnum < INPUT_STRING_COUNT; strnum++) @@ -220,6 +223,10 @@ bool validity_checker::check_all_matching(const char *string) if (m_drivlist.matches(string, m_drivlist.driver().name)) validate_one(m_drivlist.driver()); + // validate devices + if (!string) + validate_device_types(); + // cleanup validate_end(); @@ -1854,6 +1861,119 @@ void validity_checker::validate_devices() //------------------------------------------------- +// validate_devices_types - check validity of +// registered device types +//------------------------------------------------- + +void validity_checker::validate_device_types() +{ + // reset error/warning state + int start_errors = m_errors; + int start_warnings = m_warnings; + m_error_text.clear(); + m_warning_text.clear(); + m_verbose_text.clear(); + + std::unordered_map<std::string, std::add_pointer_t<device_type> > device_name_map, device_shortname_map; + std::unordered_set<std::type_index> device_types; + machine_config config(GAME_NAME(___empty), m_drivlist.options()); + for (device_type type : registered_device_types) + { + if (!device_types.emplace(type.type()).second) + { + osd_printf_error("Device class '%s' registered multiple times\n", type.type().name()); + } + else + { + device_t *const dev = config.device_add(&config.root_device(), "_tmp", type, 0); + + char const *name((dev->shortname() && *dev->shortname()) ? dev->shortname() : type.type().name()); + std::string const description((dev->source() && *dev->source()) ? util::string_format("%s(%s)", core_filename_extract_base(dev->source()).c_str(), name) : name); + + // ensure shortname exists + if (!dev->shortname() || !*dev->shortname()) + { + osd_printf_error("Device %s does not have short name defined\n", description.c_str()); + } + else + { + // check for invalid characters in shortname + for (char const *s = dev->shortname(); *s; ++s) + { + if (((*s < '0') || (*s > '9')) && ((*s < 'a') || (*s > 'z')) && (*s != '_')) + { + osd_printf_error("Device %s short name contains invalid characters\n", description.c_str()); + break; + } + } + + // check for name conflicts + auto const drvname(m_names_map.find(dev->shortname())); + auto const devname(device_shortname_map.emplace(dev->shortname(), &type)); + if (m_names_map.end() != drvname) + { + game_driver const &dup(*drvname->second); + osd_printf_error("Device %s short name is a duplicate of %s(%s)\n", description.c_str(), core_filename_extract_base(dup.source_file).c_str(), dup.name); + } + else if (!devname.second) + { + device_t *const dup = config.device_add(&config.root_device(), "_dup", *devname.first->second, 0); + osd_printf_error("Device %s short name is a duplicate of %s(%s)\n", description.c_str(), core_filename_extract_base(dup->source()).c_str(), dup->shortname()); + config.device_remove(&config.root_device(), "_dup"); + } + } + + // ensure name exists + if (!dev->name() || !*dev->name()) + { + osd_printf_error("Device %s does not have name defined\n", description.c_str()); + } + else + { + // check for description conflicts + auto const drvdesc(m_descriptions_map.find(dev->name())); + auto const devdesc(device_name_map.emplace(dev->name(), &type)); + if (m_names_map.end() != drvdesc) + { + game_driver const &dup(*drvdesc->second); + osd_printf_error("Device %s name is a duplicate of %s(%s)\n", description.c_str(), core_filename_extract_base(dup.source_file).c_str(), dup.name); + } + else if (!devdesc.second) + { + device_t *const dup = config.device_add(&config.root_device(), "_dup", *devdesc.first->second, 0); + osd_printf_error("Device %s name is a duplicate of %s(%s)\n", description.c_str(), core_filename_extract_base(dup->source()).c_str(), dup->shortname()); + config.device_remove(&config.root_device(), "_dup"); + } + } + + // ensure source exists + if (!dev->source() || !*dev->source()) + osd_printf_error("Device %s does not have source defined\n", description.c_str()); + + // check that reported type matches supplied type + if (dev->type().type() != type.type()) + osd_printf_error("Device %s reports type '%s' (created with '%s')\n", description.c_str(), dev->type().type().name(), type.type().name()); + + config.device_remove(&config.root_device(), "_tmp"); + } + } + + // if we had warnings or errors, output + if (m_errors > start_errors || m_warnings > start_warnings || !m_verbose_text.empty()) + { + output_via_delegate(OSD_OUTPUT_CHANNEL_ERROR, "%d errors, %d warnings\n", m_errors - start_errors, m_warnings - start_warnings); + if (m_errors > start_errors) + output_indented_errors(m_error_text, "Errors"); + if (m_warnings > start_warnings) + output_indented_errors(m_warning_text, "Warnings"); + if (!m_verbose_text.empty()) + output_indented_errors(m_verbose_text, "Messages"); + output_via_delegate(OSD_OUTPUT_CHANNEL_ERROR, "\n"); + } +} + + +//------------------------------------------------- // build_output_prefix - create a prefix // indicating the current source file, driver, // and device @@ -1866,7 +1986,7 @@ void validity_checker::build_output_prefix(std::string &str) // if we have a current (non-root) device, indicate that if (m_current_device != nullptr && m_current_device->owner() != nullptr) - str.append(m_current_device->name()).append(" device '").append(m_current_device->tag()+1).append("': "); + str.append(m_current_device->name()).append(" device '").append(m_current_device->tag() + 1).append("': "); // if we have a current port, indicate that as well if (m_current_ioport != nullptr) |