diff options
| author | 2017-07-21 11:47:41 +1000 | |
|---|---|---|
| committer | 2017-07-21 11:47:41 +1000 | |
| commit | 05e84dccc04849857ebc4460084bdafc872d5815 (patch) | |
| tree | f20a0a1f88d6ee1cedec9f8b2861b09acb6c0ada /src | |
| parent | 431879ef2b675540cc3987d90b4d069a49854897 (diff) | |
* Make XML file a class of its own managed with smart poitners
* Save/restore a little more of Cocoa debugger state
Diffstat (limited to 'src')
| -rw-r--r-- | src/devices/bus/ti99/gromport/cartridges.cpp | 6 | ||||
| -rw-r--r-- | src/emu/config.cpp | 10 | ||||
| -rw-r--r-- | src/emu/debug/debugcpu.cpp | 17 | ||||
| -rw-r--r-- | src/emu/render.cpp | 15 | ||||
| -rw-r--r-- | src/frontend/mame/cheat.cpp | 4 | ||||
| -rw-r--r-- | src/lib/util/xmlfile.cpp | 124 | ||||
| -rw-r--r-- | src/lib/util/xmlfile.h | 58 | ||||
| -rw-r--r-- | src/osd/modules/debugger/osx/debugview.mm | 13 | ||||
| -rw-r--r-- | src/osd/modules/debugger/osx/pointsviewer.h | 4 | ||||
| -rw-r--r-- | src/osd/modules/debugger/osx/pointsviewer.mm | 14 |
10 files changed, 139 insertions, 126 deletions
diff --git a/src/devices/bus/ti99/gromport/cartridges.cpp b/src/devices/bus/ti99/gromport/cartridges.cpp index 10780a6f0c2..24ec2670340 100644 --- a/src/devices/bus/ti99/gromport/cartridges.cpp +++ b/src/devices/bus/ti99/gromport/cartridges.cpp @@ -1707,7 +1707,6 @@ ti99_cartridge_device::rpk* ti99_cartridge_device::rpk_reader::open(emu_options util::archive_file::ptr zipfile; std::vector<char> layout_text; - util::xml::data_node *layout_xml = nullptr; int i; @@ -1736,7 +1735,7 @@ ti99_cartridge_device::rpk* ti99_cartridge_device::rpk_reader::open(emu_options layout_text[zipfile->current_uncompressed_length()] = '\0'; // Null-terminate /* parse the layout text */ - layout_xml = util::xml::data_node::string_read(&layout_text[0], nullptr); + util::xml::file::ptr const layout_xml = util::xml::file::string_read(&layout_text[0], nullptr); if (!layout_xml) throw rpk_exception(RPK_XML_ERROR); // Now we work within the XML tree @@ -1815,14 +1814,11 @@ ti99_cartridge_device::rpk* ti99_cartridge_device::rpk_reader::open(emu_options catch (rpk_exception &) { newrpk->close(); - if (layout_xml) layout_xml->file_free(); // rethrow the exception throw; } - if (layout_xml) layout_xml->file_free(); - return newrpk; } diff --git a/src/emu/config.cpp b/src/emu/config.cpp index 6c6b4c93578..bb6055fc1d9 100644 --- a/src/emu/config.cpp +++ b/src/emu/config.cpp @@ -132,9 +132,7 @@ void configuration_manager::save_settings() int configuration_manager::load_xml(emu_file &file, config_type which_type) { /* read the file */ - std::unique_ptr<util::xml::data_node, void (*)(util::xml::data_node *)> const root( - util::xml::data_node::file_read(file, nullptr), - [] (util::xml::data_node *node) { node->file_free(); }); + util::xml::file::ptr const root(util::xml::file::read(file, nullptr)); if (!root) return 0; @@ -225,9 +223,7 @@ int configuration_manager::load_xml(emu_file &file, config_type which_type) int configuration_manager::save_xml(emu_file &file, config_type which_type) { - std::unique_ptr<util::xml::data_node, void (*)(util::xml::data_node *)> const root( - util::xml::data_node::file_create(), - [] (util::xml::data_node *node) { node->file_free(); }); + util::xml::file::ptr root(util::xml::file::create()); /* if we don't have a root, bail */ if (!root) @@ -260,7 +256,7 @@ int configuration_manager::save_xml(emu_file &file, config_type which_type) } /* flush the file */ - root->file_write(file); + root->write(file); /* free and get out of here */ return 1; diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp index dfc581d478b..e682cbdafc6 100644 --- a/src/emu/debug/debugcpu.cpp +++ b/src/emu/debug/debugcpu.cpp @@ -226,8 +226,8 @@ bool debugger_cpu::comment_save() bool comments_saved = false; // if we don't have a root, bail - util::xml::data_node *const root = util::xml::data_node::file_create(); - if (root == nullptr) + util::xml::file::ptr const root = util::xml::file::create(); + if (!root) return false; // wrap in a try/catch to handle errors @@ -269,19 +269,17 @@ bool debugger_cpu::comment_save() osd_file::error filerr = file.open(m_machine.basename(), ".cmt"); if (filerr == osd_file::error::NONE) { - root->file_write(file); + root->write(file); comments_saved = true; } } } catch (emu_exception &) { - root->file_free(); return false; } // free and get out of here - root->file_free(); return comments_saved; } @@ -301,11 +299,11 @@ bool debugger_cpu::comment_load(bool is_inline) return false; // wrap in a try/catch to handle errors - util::xml::data_node *const root = util::xml::data_node::file_read(file, nullptr); + util::xml::file::ptr const root = util::xml::file::read(file, nullptr); try { // read the file - if (root == nullptr) + if (!root) throw emu_exception(); // find the config node @@ -342,13 +340,10 @@ bool debugger_cpu::comment_load(bool is_inline) catch (emu_exception &) { // clean up in case of error - if (root != nullptr) - root->file_free(); return false; } - // free the parser - root->file_free(); + // success! return true; } diff --git a/src/emu/render.cpp b/src/emu/render.cpp index 5b243306a9c..29fd2e42a63 100644 --- a/src/emu/render.cpp +++ b/src/emu/render.cpp @@ -1700,14 +1700,16 @@ bool render_target::load_layout_file(const char *dirname, const internal_layout bool render_target::load_layout_file(const char *dirname, const char *filename) { - // if the first character of the "file" is an open brace, assume it is an XML string - util::xml::data_node *rootnode; + util::xml::file::ptr rootnode; if (filename[0] == '<') - rootnode = util::xml::data_node::string_read(filename, nullptr); - - // otherwise, assume it is a file + { + // if the first character of the "file" is an open brace, assume it is an XML string + rootnode = util::xml::file::string_read(filename, nullptr); + } else { + // otherwise, assume it is a file + // build the path and optionally prepend the directory std::string fname = std::string(filename).append(".lay"); if (dirname != nullptr) @@ -1720,7 +1722,7 @@ bool render_target::load_layout_file(const char *dirname, const char *filename) return false; // read the file - rootnode = util::xml::data_node::file_read(layoutfile, nullptr); + rootnode = util::xml::file::read(layoutfile, nullptr); } // if we didn't get a properly-formatted XML file, record a warning and exit @@ -1751,7 +1753,6 @@ bool render_target::load_layout_file(const char *dirname, const char *filename) emulator_info::layout_file_cb(*rootnode); // free the root node - rootnode->file_free(); return result; } diff --git a/src/frontend/mame/cheat.cpp b/src/frontend/mame/cheat.cpp index 7e07524d2ea..06d87596e68 100644 --- a/src/frontend/mame/cheat.cpp +++ b/src/frontend/mame/cheat.cpp @@ -1403,10 +1403,10 @@ void cheat_manager::load_cheats(const char *filename) util::xml::parse_options options = { nullptr }; util::xml::parse_error error; options.error = &error; - std::unique_ptr<util::xml::data_node, void (*)(util::xml::data_node *)> rootnode(util::xml::data_node::file_read(cheatfile, &options), [] (util::xml::data_node *node) { node->file_free(); }); + util::xml::file::ptr const rootnode(util::xml::file::read(cheatfile, &options)); // if unable to parse the file, just bail - if (rootnode == nullptr) + if (!rootnode) throw emu_fatalerror("%s.xml(%d): error parsing XML (%s)\n", filename, error.error_line, error.error_message); // find the layout node diff --git a/src/lib/util/xmlfile.cpp b/src/lib/util/xmlfile.cpp index 5a6e2d7a741..893018f5384 100644 --- a/src/lib/util/xmlfile.cpp +++ b/src/lib/util/xmlfile.cpp @@ -37,7 +37,7 @@ namespace util { namespace xml { struct parse_info { XML_Parser parser; - data_node * rootnode; + file::ptr rootnode; data_node * curnode; uint32_t flags; }; @@ -60,31 +60,33 @@ static void expat_element_end(void *data, const XML_Char *name); XML FILE OBJECTS ***************************************************************************/ +file::file() { } +file::~file() { } + + /*------------------------------------------------- - file_create - create a new xml file - object + create - create a new, empty XML file -------------------------------------------------*/ -data_node *data_node::file_create() +file::ptr file::create() { - try { return new data_node(); } - catch (...) { return nullptr; } + try { return ptr(new file()); } + catch (...) { return ptr(); } } /*------------------------------------------------- - file_read - parse an XML file into its - nodes + read - parse an XML file into its nodes -------------------------------------------------*/ -data_node *data_node::file_read(util::core_file &file, parse_options const *opts) +file::ptr file::read(util::core_file &file, parse_options const *opts) { parse_info info; int done; /* set up the parser */ if (!expat_setup_parser(info, opts)) - return nullptr; + return ptr(); /* loop through the file and parse it */ do @@ -105,9 +107,9 @@ data_node *data_node::file_read(util::core_file &file, parse_options const *opts opts->error->error_column = XML_GetCurrentColumnNumber(info.parser); } - info.rootnode->file_free(); + info.rootnode.reset(); XML_ParserFree(info.parser); - return nullptr; + return ptr(); } } while (!done); @@ -116,7 +118,7 @@ data_node *data_node::file_read(util::core_file &file, parse_options const *opts XML_ParserFree(info.parser); /* return the root node */ - return info.rootnode; + return std::move(info.rootnode); } @@ -125,14 +127,14 @@ data_node *data_node::file_read(util::core_file &file, parse_options const *opts nodes -------------------------------------------------*/ -data_node *data_node::string_read(const char *string, parse_options const *opts) +file::ptr file::string_read(const char *string, parse_options const *opts) { parse_info info; int length = (int)strlen(string); /* set up the parser */ if (!expat_setup_parser(info, opts)) - return nullptr; + return ptr(); /* parse the data */ if (XML_Parse(info.parser, string, length, 1) == XML_STATUS_ERROR) @@ -144,16 +146,16 @@ data_node *data_node::string_read(const char *string, parse_options const *opts) opts->error->error_column = XML_GetCurrentColumnNumber(info.parser); } - info.rootnode->file_free(); + info.rootnode.reset(); XML_ParserFree(info.parser); - return nullptr; + return ptr(); } /* free the parser */ XML_ParserFree(info.parser); /* return the root node */ - return info.rootnode; + return std::move(info.rootnode); } @@ -161,33 +163,17 @@ data_node *data_node::string_read(const char *string, parse_options const *opts) file_write - write an XML tree to a file -------------------------------------------------*/ -void data_node::file_write(util::core_file &file) const +void file::write(util::core_file &file) const { /* ensure this is a root node */ - if (get_name()) - return; + assert(!get_name()); /* output a simple header */ file.printf("<?xml version=\"1.0\"?>\n"); file.printf("<!-- This file is autogenerated; comments and unknown tags will be stripped -->\n"); /* loop over children of the root and output */ - for (data_node const *node = get_first_child(); node; node = node->get_next_sibling()) - node->write_recursive(0, file); -} - - -/*------------------------------------------------- - file_free - free an XML file object --------------------------------------------------*/ - -void data_node::file_free() -{ - /* ensure this is a root node */ - if (get_name()) - return; - - delete this; + write_recursive(0, file); } @@ -211,7 +197,7 @@ data_node::data_node(data_node *parent, const char *name, const char *value) : line(0) , m_next(nullptr) , m_first_child(nullptr) - , m_name(name ? name : "") + , m_name(name) , m_value(value ? value : "") , m_parent(parent) , m_attributes() @@ -356,6 +342,9 @@ data_node const *data_node::find_next_matching_sibling(const char *name, const c data_node *data_node::add_child(const char *name, const char *value) { + if (!name || !*name) + return nullptr; + /* new element: create a new node */ data_node *node; try { node = new data_node(this, name, value); } @@ -743,10 +732,10 @@ static bool expat_setup_parser(parse_info &info, parse_options const *opts) } /* create a root node */ - info.rootnode = data_node::file_create(); - if (info.rootnode == nullptr) + info.rootnode = file::create(); + if (!info.rootnode) return false; - info.curnode = info.rootnode; + info.curnode = info.rootnode.get(); /* create the XML parser */ memcallbacks.malloc_fcn = expat_malloc; @@ -755,7 +744,7 @@ static bool expat_setup_parser(parse_info &info, parse_options const *opts) info.parser = XML_ParserCreate_MM(nullptr, &memcallbacks, nullptr); if (info.parser == nullptr) { - info.rootnode->file_free(); + info.rootnode.reset(); return false; } @@ -867,36 +856,45 @@ void data_node::add_attribute(const char *name, const char *value) void data_node::write_recursive(int indent, util::core_file &file) const { - /* output this tag */ - file.printf("%*s<%s", indent, "", get_name()); - - /* output any attributes */ - for (attribute_node const &anode : m_attributes) - file.printf(" %s=\"%s\"", anode.name, anode.value); - - if (!get_first_child() && !get_value()) + if (!get_name()) { - /* if there are no children and no value, end the tag here */ - file.printf(" />\n"); + /* root node doesn't generate tag */ + for (data_node const *child = this->get_first_child(); child; child = child->get_next_sibling()) + child->write_recursive(indent, file); } else { - /* otherwise, close this tag and output more stuff */ - file.printf(">\n"); + /* output this tag */ + file.printf("%*s<%s", indent, "", get_name()); - /* if there is a value, output that here */ - if (get_value()) - file.printf("%*s%s\n", indent + 4, "", get_value()); + /* output any attributes */ + for (attribute_node const &anode : m_attributes) + file.printf(" %s=\"%s\"", anode.name, anode.value); - /* loop over children and output them as well */ - if (get_first_child()) + if (!get_first_child() && !get_value()) { - for (data_node const *child = this->get_first_child(); child; child = child->get_next_sibling()) - child->write_recursive(indent + 4, file); + /* if there are no children and no value, end the tag here */ + file.printf(" />\n"); } + else + { + /* otherwise, close this tag and output more stuff */ + file.printf(">\n"); - /* write a closing tag */ - file.printf("%*s</%s>\n", indent, "", get_name()); + /* if there is a value, output that here */ + if (get_value()) + file.printf("%*s%s\n", indent + 4, "", get_value()); + + /* loop over children and output them as well */ + if (get_first_child()) + { + for (data_node const *child = this->get_first_child(); child; child = child->get_next_sibling()) + child->write_recursive(indent + 4, file); + } + + /* write a closing tag */ + file.printf("%*s</%s>\n", indent, "", get_name()); + } } } diff --git a/src/lib/util/xmlfile.h b/src/lib/util/xmlfile.h index c8f8c4ae4c6..5c4672373d3 100644 --- a/src/lib/util/xmlfile.h +++ b/src/lib/util/xmlfile.h @@ -73,25 +73,6 @@ public: }; - - /* ----- XML file objects ----- */ - - // create a new empty xml file object - static data_node *file_create(); - - // parse an XML file into its nodes */ - static data_node *file_read(util::core_file &file, parse_options const *opts); - - /* parse an XML string into its nodes */ - static data_node *string_read(const char *string, parse_options const *opts); - - // write an XML tree to a file - void file_write(util::core_file &file) const; - - // free an XML file object - void file_free(); - - /* ----- XML node management ----- */ char const *get_name() const { return m_name.empty() ? nullptr : m_name.c_str(); } @@ -141,7 +122,6 @@ public: void delete_node(); - /* ----- XML attribute management ----- */ // return whether a node has the specified attribute @@ -176,6 +156,13 @@ public: int line; /* line number for this node's start */ +protected: + data_node(); + ~data_node(); + + void write_recursive(int indent, util::core_file &file) const; + + private: // a node representing an attribute struct attribute_node @@ -187,9 +174,7 @@ private: }; - data_node(); data_node(data_node *parent, const char *name, const char *value); - ~data_node(); data_node(data_node const &) = delete; data_node(data_node &&) = delete; @@ -204,8 +189,6 @@ private: attribute_node *get_attribute(const char *attribute); attribute_node const *get_attribute(const char *attribute) const; - void write_recursive(int indent, util::core_file &file) const; - data_node * m_next; data_node * m_first_child; @@ -216,6 +199,33 @@ private: }; +// a node representing the root of a document +class file : public data_node +{ +public: + using ptr = std::unique_ptr<file>; + + + ~file(); + + // create a new empty xml file object + static ptr create(); + + // parse an XML file into its nodes + static ptr read(util::core_file &file, parse_options const *opts); + + // parse an XML string into its nodes + static ptr string_read(const char *string, parse_options const *opts); + + // write an XML tree to a file + void write(util::core_file &file) const; + + +private: + file(); +}; + + /*************************************************************************** FUNCTION PROTOTYPES diff --git a/src/osd/modules/debugger/osx/debugview.mm b/src/osd/modules/debugger/osx/debugview.mm index ed03d7e728c..26d84d6038d 100644 --- a/src/osd/modules/debugger/osx/debugview.mm +++ b/src/osd/modules/debugger/osx/debugview.mm @@ -844,11 +844,14 @@ static void debugwin_view_update(debug_view &view, void *osdprivate) - (void)keyUp:(NSEvent *)event { - debug_view_xy const pos = view->cursor_position(); - [self scrollRectToVisible:NSMakeRect((pos.x * fontWidth) + [textContainer lineFragmentPadding], - pos.y * fontHeight, - fontWidth, - fontHeight)]; // FIXME: metrics + if (view->cursor_supported() && view->cursor_visible()) + { + debug_view_xy const pos = view->cursor_position(); + [self scrollRectToVisible:NSMakeRect((pos.x * fontWidth) + [textContainer lineFragmentPadding], + pos.y * fontHeight, + fontWidth, + fontHeight)]; // FIXME: metrics + } } diff --git a/src/osd/modules/debugger/osx/pointsviewer.h b/src/osd/modules/debugger/osx/pointsviewer.h index fab1872d1ac..21deb79aa93 100644 --- a/src/osd/modules/debugger/osx/pointsviewer.h +++ b/src/osd/modules/debugger/osx/pointsviewer.h @@ -18,7 +18,8 @@ @interface MAMEPointsViewer : MAMEAuxiliaryDebugWindowHandler { - NSTabView *tabs; + NSTabView *tabs; + NSPopUpButton *subviewButton; } - (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c; @@ -26,5 +27,6 @@ - (IBAction)changeSubview:(id)sender; - (void)saveConfigurationToNode:(util::xml::data_node *)node; +- (void)restoreConfigurationFromNode:(util::xml::data_node const *)node; @end diff --git a/src/osd/modules/debugger/osx/pointsviewer.mm b/src/osd/modules/debugger/osx/pointsviewer.mm index d6333514d95..8bd4dad3a1b 100644 --- a/src/osd/modules/debugger/osx/pointsviewer.mm +++ b/src/osd/modules/debugger/osx/pointsviewer.mm @@ -21,7 +21,7 @@ MAMEDebugView *breakView, *watchView; NSScrollView *breakScroll, *watchScroll; NSTabViewItem *breakTab, *watchTab; - NSPopUpButton *actionButton, *subviewButton; + NSPopUpButton *actionButton; NSRect subviewFrame; if (!(self = [super initWithMachine:m title:@"(Break|Watch)points" console:c])) @@ -147,6 +147,18 @@ - (void)saveConfigurationToNode:(util::xml::data_node *)node { [super saveConfigurationToNode:node]; node->set_attribute_int("type", MAME_DEBUGGER_WINDOW_TYPE_POINTS_VIEWER); + node->set_attribute_int("bwtype", [tabs indexOfTabViewItem:[tabs selectedTabViewItem]]); +} + + +- (void)restoreConfigurationFromNode:(util::xml::data_node const *)node { + [super restoreConfigurationFromNode:node]; + int const tab = node->get_attribute_int("bwtype", [tabs indexOfTabViewItem:[tabs selectedTabViewItem]]); + if ((0 <= tab) && ([tabs numberOfTabViewItems] > tab)) + { + [subviewButton selectItemAtIndex:tab]; + [self changeSubview:subviewButton]; + } } @end |
