summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2017-07-21 11:47:41 +1000
committer Vas Crabb <vas@vastheman.com>2017-07-21 11:47:41 +1000
commit05e84dccc04849857ebc4460084bdafc872d5815 (patch)
treef20a0a1f88d6ee1cedec9f8b2861b09acb6c0ada /src
parent431879ef2b675540cc3987d90b4d069a49854897 (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.cpp6
-rw-r--r--src/emu/config.cpp10
-rw-r--r--src/emu/debug/debugcpu.cpp17
-rw-r--r--src/emu/render.cpp15
-rw-r--r--src/frontend/mame/cheat.cpp4
-rw-r--r--src/lib/util/xmlfile.cpp124
-rw-r--r--src/lib/util/xmlfile.h58
-rw-r--r--src/osd/modules/debugger/osx/debugview.mm13
-rw-r--r--src/osd/modules/debugger/osx/pointsviewer.h4
-rw-r--r--src/osd/modules/debugger/osx/pointsviewer.mm14
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