Browse files

XMLParser now working

  • Loading branch information...
1 parent b660b46 commit 85a771b6895e626999a7e7aa52903b18050512e6 @Grumbel committed May 12, 2009
Showing with 118 additions and 87 deletions.
  1. +1 −1 NEWS
  2. +1 −1 SConstruct
  3. +0 −14 TODO
  4. +5 −0 src/joystick.cpp
  5. +2 −0 src/joystick.hpp
  6. +10 −4 src/main.cpp
  7. +4 −1 src/main.hpp
  8. +65 −45 src/{xml_tree.cpp → xml_parser.cpp}
  9. +30 −21 src/{xml_tree.hpp → xml_parser.hpp}
View
2 NEWS
@@ -1,7 +1,7 @@
jstest-gtk 0.1.1 (2009-05-??)
=============================
-* removed accidental boost dependency
+* removed accidental boost and gtkglextmm-1.2 dependencies
* improved support for PS3 controller and other with huge axis/button counts
* implemented calibration wizard
* added man-page
View
2 SConstruct
@@ -19,7 +19,7 @@ env = Environment(CXXFLAGS=["-g", "-Wall", "-Werror"],
LIBS=["expat"])
env.ParseConfig('pkg-config --cflags --libs gtkmm-2.4 gtkglextmm-1.2 sigc++-2.0')
env.Program('jscfg-test', ['src/joystick_configuration.cpp'])
-env.Program('xml-test', ['src/xml_tree.cpp'])
+env.Program('xml-test', ['src/xml_parser.cpp'], CPPDEFINES=['__TEST__'])
env.Program('jstest-gtk', [
'src/axis_widget.cpp',
'src/button_widget.cpp',
View
14 TODO
@@ -14,13 +14,6 @@ git push --tags
==========
* implement command line load/save
- Syntax:
-
-
- joystickname
- calibration
- buttonmapping
- axismapping
* use while loop in Joystick::update
@@ -56,13 +49,6 @@ git push --tags
* Joystick Database, base it on evdev, not joydev:
-<joystick>
- <name>Sony PLAYSTATION(R)3 Controller</name>
- <image>playstotion3.svg</image>
- <axis-count>28</axis-count>
- <button-count>18</button-count>
-</joystick>
-
* [FEATURE] Watch teh system, maybe being in systray, to protect the
device from accidental reconfiguration by another
application. (unlikely, as that would mean polling and other then
View
5 src/joystick.cpp
@@ -366,5 +366,10 @@ Joystick::set_axis_mapping(const std::vector<int>& mapping)
throw std::runtime_error(str.str());
}
}
+
+void
+Joystick::save(std::ostream& out)
+{
+}
/* EOF */
View
2 src/joystick.hpp
@@ -86,6 +86,8 @@ class Joystick
void set_button_mapping(const std::vector<int>& mapping);
void set_axis_mapping(const std::vector<int>& mapping);
+ void save(std::ostream& out);
+
private:
Joystick(const Joystick&);
Joystick& operator=(const Joystick&);
View
14 src/main.cpp
@@ -31,6 +31,7 @@
Main* Main::current_ = 0;
Main::Main()
+ : list_dialog(0)
{
current_ = this;
}
@@ -42,10 +43,15 @@ Main::~Main()
void
Main::show_device_list_dialog()
{
- JoystickListWidget* dialog = new JoystickListWidget();
- dialogs.push_back(dialog);
- dialog->show_all();
- dialog->signal_hide().connect(sigc::bind(sigc::mem_fun(this, &Main::on_dialog_hide), dialog));
+ if (list_dialog)
+ {
+ list_dialog->show();
+ }
+ else
+ {
+ list_dialog = new JoystickListWidget();
+ list_dialog->show_all();
+ }
}
void
View
5 src/main.hpp
@@ -23,6 +23,7 @@
#include <gtkmm/dialog.h>
class Joystick;
+class JoystickListWidget;
class Main
{
@@ -32,7 +33,9 @@ class Main
static Main* current() { return current_; }
private:
- std::vector<Joystick*> joysticks;
+ JoystickListWidget* list_dialog;
+
+ std::vector<Joystick*> joysticks;
std::vector<Gtk::Dialog*> dialogs;
void on_dialog_hide(Gtk::Dialog* dialog);
View
110 src/xml_tree.cpp → src/xml_parser.cpp
@@ -22,51 +22,80 @@
#include <sstream>
#include <expat.h>
-#include "xml_tree.hpp"
+#include "xml_parser.hpp"
+// static C functions that map back to the C++ member functions
+void
+XMLParser::start_element(void* userdata, const char* el, const char** attr)
+{
+ static_cast<XMLParser*>(userdata)->on_start_element(el, attr);
+}
+
+void
+XMLParser::end_element(void* userdata, const char* el)
+{
+ static_cast<XMLParser*>(userdata)->on_end_element(el);
+}
+
+void
+XMLParser::character_data(void* userdata, const char* s, int len)
+{
+ static_cast<XMLParser*>(userdata)->on_character_data(s, len);
+}
+
+std::auto_ptr<XMLNode>
+XMLParser::parse(const std::string& filename)
+{
+ XMLParser tree(filename);
+ return tree.get_root();
+}
-XMLTree::XMLTree(const std::string& filename_)
+XMLParser::XMLParser(const std::string& filename_)
: filename(filename_),
- root_node(0)
+ parser(0)
{
- std::cout << "Trying to read: " << filename << std::endl;
-
std::vector<char> data;
- { // Read the file into the vector
+ { // Read the file into the vector data
std::ifstream in(filename.c_str(), std::ios::binary);
- in.seekg (0, std::ios::end);
- data.resize(in.tellg());
- in.seekg (0, std::ios::beg);
- in.read(&*data.begin(), data.size());
- in.close();
+ if (!in)
+ {
+ throw std::runtime_error("couldn't open: " + filename);
+ }
+ else
+ {
+ in.seekg (0, std::ios::end);
+ data.resize(in.tellg());
+ in.seekg (0, std::ios::beg);
+ in.read(&*data.begin(), data.size());
+ }
}
parser = XML_ParserCreate(NULL);
XML_SetUserData(parser, this);
- XML_SetElementHandler(parser, &XMLTree::start_element, &XMLTree::end_element);
- XML_SetCharacterDataHandler(parser, &XMLTree::character_data);
+ XML_SetElementHandler(parser, &start_element, &end_element);
+ XML_SetCharacterDataHandler(parser, &character_data);
if (XML_Parse(parser, &*data.begin(), data.size(), 0) == XML_STATUS_ERROR)
{
std::ostringstream out;
out << filename << ":" << XML_GetCurrentLineNumber(parser)
<< ": parse error: " << XML_ErrorString(XML_GetErrorCode(parser));
- XML_ParserFree(parser);
throw std::runtime_error(out.str());
}
-
- XML_ParserFree(parser);
}
-XMLTree::~XMLTree()
+XMLParser::~XMLParser()
{
- delete root_node;
+ XML_ParserFree(parser);
}
void
-XMLTree::on_start_element(const char* name, const char** attr)
+XMLParser::on_start_element(const char* name, const char** attr)
{
+ if (*attr)
+ raise_error("attribute not allowed");
+
// spaces are ignored, everything else is an error
for(int i = 0; i < (int)cdata.size(); ++i)
if (!isspace(cdata[i]))
@@ -76,9 +105,9 @@ XMLTree::on_start_element(const char* name, const char** attr)
if (!node.empty())
{
XMLListNode* new_node = new XMLListNode(node);
- if (!root_node)
+ if (!root_node.get())
{
- root_node = new_node;
+ root_node.reset(new_node);
}
else
{
@@ -91,7 +120,7 @@ XMLTree::on_start_element(const char* name, const char** attr)
}
void
-XMLTree::on_end_element(const char* el)
+XMLParser::on_end_element(const char* el)
{
if (!node.empty() && !cdata.empty())
{
@@ -113,46 +142,37 @@ XMLTree::on_end_element(const char* el)
}
void
-XMLTree::on_character_data(const char* s, int len)
+XMLParser::on_character_data(const char* s, int len)
{
cdata += std::string(s, len);
}
void
-XMLTree::raise_error(const std::string& str)
+XMLParser::raise_error(const std::string& str)
{
std::ostringstream out;
out << filename << ":" << XML_GetCurrentLineNumber(parser) << ": " << str;
throw std::runtime_error(out.str());
}
-void
-XMLTree::start_element(void* userdata, const char* el, const char** attr)
-{
- static_cast<XMLTree*>(userdata)->on_start_element(el, attr);
-}
-
-void
-XMLTree::end_element(void* userdata, const char* el)
-{
- static_cast<XMLTree*>(userdata)->on_end_element(el);
-}
-
-void
-XMLTree::character_data(void* userdata, const char* s, int len)
-{
- static_cast<XMLTree*>(userdata)->on_character_data(s, len);
-}
-
+#ifdef __TEST__
int main(int argc, char** argv)
{
- for(int i = 1; i < argc; ++i)
+ try
+ {
+ for(int i = 1; i < argc; ++i)
+ {
+ std::auto_ptr<XMLNode> root = XMLParser::parse(argv[i]);
+ root->print(std::cout);
+ }
+ }
+ catch(std::exception& err)
{
- XMLTree tree(argv[i]);
- tree.get_root()->print(std::cout);
+ std::cout << "Error: " << err.what() << std::endl;
}
return 0;
}
+#endif
/* EOF */
View
51 src/xml_tree.hpp → src/xml_parser.hpp
@@ -20,15 +20,23 @@
#define HEADER_JSTREE_GTK_XML_TREE_HPP
#include <vector>
+#include <memory>
#include <iostream>
+
+/*
+ * The code below does not produce a full DOM, but a drastically
+ * simplified one, namely nodes can either contain text or they can
+ * contain child nodes, but not both. Nodes are also not allowed to
+ * have attributes.
+ */
class XMLNode
{
public:
XMLNode() {}
virtual ~XMLNode() {}
- virtual void print(std::ostream& out) =0;
+ virtual void print(std::ostream& out, int depth = 0) =0;
};
class XMLListNode : public XMLNode
@@ -50,14 +58,14 @@ class XMLListNode : public XMLNode
}
}
- void print(std::ostream& out)
+ void print(std::ostream& out, int depth = 0)
{
- std::cout << "<" << name << ">" << std::endl;
+ std::cout << std::string(2*depth, ' ') << "<" << name << ">" << std::endl;
for(std::vector<XMLNode*>::iterator i = children.begin(); i != children.end(); ++i)
{
- (*i)->print(out);
+ (*i)->print(out, depth + 1);
}
- std::cout << "</" << name << ">" << std::endl;
+ std::cout << std::string(2*depth, ' ') << "</" << name << ">" << std::endl;
}
private:
@@ -76,47 +84,48 @@ class XMLDataNode : public XMLNode
data(data_)
{}
- void print(std::ostream& out) {
- out << "<" << name << ">" << data << "</" << name << ">" << std::endl;
+ void print(std::ostream& out, int depth = 0)
+ {
+ out << std::string(2*depth, ' ') << "<" << name << ">" << data << "</" << name << ">" << std::endl;
}
private:
XMLDataNode(const XMLDataNode&);
XMLDataNode& operator=(const XMLDataNode&);
};
-class XMLTree
+class XMLParser
{
-private:
- // static C-like helper functions for expat
- static void start_element(void* userdata, const char* el, const char** attr);
- static void end_element(void* userdata, const char* el);
- static void character_data(void* userdata, const char* s, int len);
+public:
+ static std::auto_ptr<XMLNode> parse(const std::string& filename);
private:
std::string filename;
XML_Parser parser;
- XMLNode* root_node;
+ std::auto_ptr<XMLNode> root_node;
std::vector<XMLListNode*> node_stack;
- XMLListNode* current_node;
std::string node;
std::string cdata;
-public:
- XMLTree(const std::string& filename);
- ~XMLTree();
+ XMLParser(const std::string& filename);
+ ~XMLParser();
+
+ std::auto_ptr<XMLNode> get_root() { return root_node; }
- XMLNode* get_root() const { return root_node; }
void on_start_element(const char* el, const char** attr);
void on_end_element(const char* el);
void on_character_data(const char* s, int len);
void raise_error(const std::string& str);
private:
- XMLTree(const XMLTree&);
- XMLTree& operator=(const XMLTree&);
+ static void start_element(void* userdata, const char* el, const char** attr);
+ static void end_element(void* userdata, const char* el);
+ static void character_data(void* userdata, const char* s, int len);
+
+ XMLParser(const XMLParser&);
+ XMLParser& operator=(const XMLParser&);
};
#endif

0 comments on commit 85a771b

Please sign in to comment.