diff options
author | 2017-07-21 13:03:44 +1000 | |
---|---|---|
committer | 2017-07-21 13:03:44 +1000 | |
commit | d7984c7d0ce594ecb34275fdabb817bdbe261647 (patch) | |
tree | b8a771b129db3ca6105111e202b0d1deab813999 | |
parent | 05e84dccc04849857ebc4460084bdafc872d5815 (diff) |
Add a method for copying part of an XML tree into another tree and use it to fix Cocoa debugger fatal error
-rw-r--r-- | src/lib/util/xmlfile.cpp | 60 | ||||
-rw-r--r-- | src/lib/util/xmlfile.h | 7 | ||||
-rw-r--r-- | src/osd/modules/debugger/debugosx.mm | 26 |
3 files changed, 81 insertions, 12 deletions
diff --git a/src/lib/util/xmlfile.cpp b/src/lib/util/xmlfile.cpp index 893018f5384..11d18482e33 100644 --- a/src/lib/util/xmlfile.cpp +++ b/src/lib/util/xmlfile.cpp @@ -70,7 +70,7 @@ file::~file() { } file::ptr file::create() { - try { return ptr(new file()); } + try { return ptr(new file); } catch (...) { return ptr(); } } @@ -213,7 +213,12 @@ data_node::data_node(data_node *parent, const char *name, const char *value) data_node::~data_node() { - /* free the children */ + free_children(); +} + + +void data_node::free_children() +{ for (data_node *nchild = nullptr; m_first_child; m_first_child = nchild) { /* note the next node and free this node */ @@ -382,6 +387,43 @@ data_node *data_node::get_or_add_child(const char *name, const char *value) } +// recursively copy as child of another node +data_node *data_node::copy_into(data_node &parent) const +{ + data_node *const result = parent.add_child(get_name(), get_value()); + result->m_attributes = m_attributes; + + data_node *dst = result; + data_node const *src = get_first_child(); + while (src && (&parent != dst)) + { + dst = dst->add_child(src->get_name(), src->get_value()); + dst->m_attributes = src->m_attributes; + data_node const *next = src->get_first_child(); + if (next) + { + src = next; + } + else + { + dst = dst->get_parent(); + next = src->get_next_sibling(); + if (next) + { + src = next; + } + else + { + dst = dst->get_parent(); + src = src->get_parent()->get_next_sibling(); + } + } + } + + return result; +} + + /*------------------------------------------------- delete_node - delete a node and its children @@ -389,9 +431,10 @@ data_node *data_node::get_or_add_child(const char *name, const char *value) void data_node::delete_node() { - /* first unhook us from the list of children of our parent */ + /* don't allow deletion of document root */ if (m_parent) { + /* first unhook us from the list of children of our parent */ for (data_node **pnode = &m_parent->m_first_child; *pnode; pnode = &(*pnode)->m_next) { if (*pnode == this) @@ -400,10 +443,15 @@ void data_node::delete_node() break; } } - } - /* now free ourselves and our children */ - delete this; + /* now free ourselves and our children */ + delete this; + } + else + { + /* remove all children of document root */ + free_children(); + } } diff --git a/src/lib/util/xmlfile.h b/src/lib/util/xmlfile.h index 5c4672373d3..5e55dbf310e 100644 --- a/src/lib/util/xmlfile.h +++ b/src/lib/util/xmlfile.h @@ -118,6 +118,9 @@ public: // either return an existing child node or create one if it doesn't exist data_node *get_or_add_child(const char *name, const char *value); + // recursively copy as child of another node + data_node *copy_into(data_node &parent) const; + // delete a node and its children void delete_node(); @@ -189,6 +192,8 @@ private: attribute_node *get_attribute(const char *attribute); attribute_node const *get_attribute(const char *attribute) const; + void free_children(); + data_node * m_next; data_node * m_first_child; @@ -208,7 +213,7 @@ public: ~file(); - // create a new empty xml file object + // create a new, empty XML file static ptr create(); // parse an XML file into its nodes diff --git a/src/osd/modules/debugger/debugosx.mm b/src/osd/modules/debugger/debugosx.mm index 0c0cbb60337..adb32fea199 100644 --- a/src/osd/modules/debugger/debugosx.mm +++ b/src/osd/modules/debugger/debugosx.mm @@ -30,6 +30,8 @@ #import "osx/debugconsole.h" #import "osx/debugwindowhandler.h" +#include "util/xmlfile.h" + #include <atomic> @@ -44,7 +46,8 @@ public: osd_module(OSD_DEBUG_PROVIDER, "osx"), debug_module(), m_machine(nullptr), - m_console(nil) + m_console(nil), + m_config() { } @@ -69,6 +72,7 @@ private: running_machine *m_machine; MAMEDebugConsole *m_console; + util::xml::file::ptr m_config; static std::atomic_bool s_added_menus; }; @@ -141,6 +145,11 @@ void debugger_osx::wait_for_debugger(device_t &device, bool firststop) // make sure the debug windows are visible if (firststop) { + if (m_config) + { + [m_console loadConfiguration:m_config->get_first_child()]; + m_config.reset(); + } NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:[NSValue valueWithPointer:&device], @"MAMEDebugDevice", [NSValue valueWithPointer:m_machine], @@ -296,10 +305,17 @@ void debugger_osx::config_load(config_type cfgtype, util::xml::data_node const * { if ((config_type::GAME == cfgtype) && parentnode) { - NSAutoreleasePool *const pool = [[NSAutoreleasePool alloc] init]; - create_console(); - [m_console loadConfiguration:parentnode]; - [pool release]; + if (m_console) + { + NSAutoreleasePool *const pool = [[NSAutoreleasePool alloc] init]; + [m_console loadConfiguration:parentnode]; + [pool release]; + } + else + { + m_config = util::xml::file::create(); + parentnode->copy_into(*m_config); + } } } |