-DEBUG=-g3 -DDEBUG -Wall
-#CPPFLAGS=-g3 -Wall -I/usr/include/libxml++-1.0 -I/usr/include/libxml2 -DDEBUG
-#CPPFLAGS=-O3 -Wall -I/usr/include/libxml++-1.0 -I/usr/include/libxml2
+LIBBIFE_DIR=libbife
-TAGETS=hit.o ghit.o chit.o widget.o container.o fallback.o string.o
+DEBUG=-Wall -g3 -DDEBUG
+CPPFLAGS=-I/usr/include/libxml++-1.0 -I/usr/include/libxml2 $(DEBUG)
+LDFLAGS=-L$(LIBBIFE_DIR) -lxml++-0.1 -ldl -lbife
all: parser_test
-main: $(TAGETS)
-
-
-CPPFLAGS=-fPIC $(DEBUG)
-
-hit.o: hit.h hit.cpp
-ghit.o: hit.o ghit.h ghit.cpp
-chit.o: ghit.o chit.h chit.cpp
-
-widget.o: widget.h widget.cpp
-string.o: widget.o string.h string.cpp
-container.o: widget.o container.h container.cpp
-fallback.o: container.o fallback.h fallback.cpp
-
-translate.o: translate.h translate.cpp
-translate_loader.o: translate_loader.cpp
-#.o: .o .h .cpp
-
-# LIBBIFE
-LIBBIFE_TARGETS=hit.o ghit.o chit.o widget.o string.o container.o fallback.o
-libbife.so: $(LIBBIFE_TARGETS)
- $(CXX) $(DEBUG) -Wl,-soname,libbife.so -shared -o libbife.so $(LIBBIFE_TARGETS)
-
-# TRANSLATE FALLBACK PLUG-IN
-TRANSLATE_TARGETS=translate.o translate_loader.o
-translate.so: libbife.so $(TRANSLATE_TARGETS)
- $(CXX) $(DEBUG) -L. -lbife -Wl,-soname,translate.so -shared -o translate.so $(TRANSLATE_TARGETS)
-
-
# Parser example.
-PARSER_FLAGS=-I/usr/include/libxml++-1.0 -I/usr/include/libxml2
parser.o: parser.h parser.cpp
- $(CXX) $(DEBUG) $(PARSER_FLAGS) -c parser.cpp
parser_test.o: parser_test.cpp
- $(CXX) $(DEBUG) $(PARSER_FLAGS) -c parser_test.cpp
-PARSER_TARGETS=parser.o parser_test.o
-parser_test: translate.so $(PARSER_TARGETS)
- $(CXX) $(DEBUG) $(PARSER_FLAGS) -L. -lxml++-0.1 -ldl -lbife -o parser_test $(PARSER_TARGETS)
- @echo
- @echo ----------------------------------------------
- @echo export LD_LIBRARY_PATH=.
- @echo to use ./parser_test
+parser_test: parser.o parser_test.o
clean:
- @rm -f *.o main parser_test
+ @rm -f *.o parser_test
+
--- /dev/null
+
+DEBUG=-Wall #-g3 -DDEBUG
+CPPFLAGS=-fPIC $(DEBUG)
+LDFLAGS=-shared
+
+all: libbife.so
+
+hit.o: hash.h hit.h hit.cpp
+ghit.o: hit.o ghit.h ghit.cpp
+chit.o: ghit.o chit.h chit.cpp
+
+widget.o: hit.o widget.h widget.cpp
+string.o: widget.o string.h string.cpp
+container.o: widget.o container.h container.cpp
+fallback.o: container.o fallback.h fallback.cpp
+
+TAGETS=hit.o ghit.o chit.o widget.o string.o container.o fallback.o
+libbife.so: $(TAGETS)
+ $(CXX) $(DEBUG) $(LDFLAGS) -o libbife.so $(TAGETS)
+
+clean:
+ @rm -f *.o libbife.so
+
* @todo
*/
class Fallback: public Container {
+ // Typedefs
+ public:
+ /// Fallback constructor function prototype.
+ typedef Fallback* Constructor(const string&, const string&, const Hash&);
+
// Attributes.
public:
/// Root widget.
* @todo
*/
class Widget {
+ // Typedefs
+ public:
+ /// Widget constructor function prototype.
+ typedef Widget* Constructor(const string&, const Hash&);
+ /// Widget destructor function prototype.
+ typedef void Destructor(Widget*);
+
// Attributes.
public:
/// Widget attributes.
// vim: set expandtab tabstop=4 shiftwidth=4:
-#include "widget.h"
-#include "container.h"
-#include "fallback.h"
-#include "string.h"
+#include "libbife/widget.h"
+#include "libbife/container.h"
+#include "libbife/fallback.h"
+#include "libbife/string.h"
#include "parser.h"
-#include <sstream>
+//#include <sstream>
#include <dlfcn.h>
-using std::stringstream;
+//using std::stringstream;
using namespace bife;
#ifdef DEBUG
}
cerr << "]);" << endl;
#endif
- stack.push(fb_create(name, attrs));
+ if (fbClass.empty()) {
+ throw string("Widget '") + name + "' not found and now using a fallback class.";
+ } else {
+ stack.push(fbNew(fbClass, name, attrs));
+ }
}
void Parser::on_end_element(const string& name) {
#endif
}
-Parser::Parser(void): fb_create(NULL), fb_destroy(NULL), root(NULL) {
+/*
+Parser::Parser(void): fallbackConstructor(NULL), fallbackDestructor(NULL), root(NULL) {
#ifdef DEBUG
cerr << "In Parser::Parser();" << endl;
#endif
- void* fb = dlopen("./translate.so", RTLD_NOW | RTLD_GLOBAL); // TODO - mas rapido: RTLD_LAZY);
+ void* fb = dlopen("./translate.so", RTLD_LAZY); // XXX - así anda: RTLD_NOW | RTLD_GLOBAL);
if (!fb) {
throw string("No se puede cargar el plug-in: ") + dlerror();
}
throw string("No se puede cargar el creador del plug-in: ") + dlerror();
}
}
+*/
-//Parser::Parser(const Hash& attrs): attrs(attrs) {
-//#ifdef DEBUG
-// cerr << "In Parser::Parser(attrs = {" /* TODO << attrs */ << "});" << endl;
-//#endif
-//}
+Parser::Parser(const string& fallback): fbNew(NULL), fbDel(NULL), root(NULL) {
+#ifdef DEBUG
+ cerr << "In Parser::Parser(fallback = '" << fallback << "');" << endl;
+#endif
+ if (!fallback.empty()) {
+ string::size_type pos = fallback.find(".");
+ if (pos == string::npos) {
+ throw string("Fallback module not specified in fallback name: ") + fallback;
+ }
+ fbClass = fallback.substr(pos + 1, fallback.length() - 1);
+ // Opens the fallback module.
+ string modules_dir = "translate";
+ string fb_module = modules_dir + "/" + fallback.substr(0, pos) + ".so";
+ void* dlh = dlopen(fb_module.c_str(), RTLD_LAZY);
+ if (!dlh) {
+ throw string("No se puede cargar el plug-in: ") + dlerror();
+ }
+ fbNew = (Fallback::Constructor*)dlsym(dlh, "fallback_constructor");
+ fbDel = (Widget::Destructor*)dlsym(dlh, "widget_destructor");
+ if (!fbNew || !fbDel) {
+ throw string("No se puede cargar el creador del plug-in: ") + dlerror();
+ }
+ // TODO - CLOSE dl handler, destroy objects.
+ }
+}
Parser::~Parser(void) {
#ifdef DEBUG
#ifndef BIFE_PARSER_H
#define BIFE_PARSER_H
-#include "hit.h"
-#include "hash.h"
-#include "widget.h"
+#include "libbife/hit.h"
+#include "libbife/hash.h"
+#include "libbife/widget.h"
+#include "libbife/fallback.h"
#include <libxml++/libxml++.h>
#include <string>
#include <stack>
-// FIXME - Poner esto en un lugar más bonito.
-typedef bife::Widget* create_t(const std::string& name, const bife::Hash&);
-typedef void destroy_t(bife::Widget*);
-
namespace bife {
using std::string;
/**
* Base Widget Class.
*
- * @todo
+ * @todo Better plug-in support. Cleanning (a lot).
+ * @todo Try to free some memeory :)
*/
class Parser: public xmlpp::SaxParser {
// Typedefs.
protected:
+ /// Stack of widget pointers.
typedef std::stack<Widget*> WidgetStack;
// Attributes.
protected:
- /// Stack TODO.
+ /**
+ * Widget stack.
+ * This is the stack of widgets to know what widget is the parser
+ * proccesing.
+ */
WidgetStack stack;
- // TODO Fallback.
- create_t* fb_create;
- destroy_t* fb_destroy;
+ /// Fallback constructor function pointer.
+ Fallback::Constructor* fbNew;
+
+ /// Fallback destructor function pointer.
+ Widget::Destructor* fbDel;
+
+ /// Fallback class name.
+ string fbClass;
public:
- /// Widget attributes.
+ /// Widget attributes (FIXME - this must be protected?).
Widget* root;
// Methods.
/**
* Constructor.
*/
- Parser(void);
+ //Parser(void);
/**
* Constructor.
*
- * @param fallback Fallback.
+ * @param fallback Fallback class name.
*/
- //Parser(const Fallback&); TODO
+ Parser(const string& = "");
/**
* Destructor.
// vim: set expandtab tabstop=4 shiftwidth=4:
-#include "chit.h"
+#include "libbife/chit.h"
#include "parser.h"
#include <sstream>
#include <iostream>
cout << "Parser example:" << endl;
cout << "===============" << endl;
try {
- Parser parser;
+ Parser parser("translate.translate");
parser.parse_file(file);
// Text is returned in utf-8 encoding.
cout << parser.root->render(tpl) << endl;
} catch (string e) {
cerr << "Error: " << e << endl;
return 2;
+ } catch (const char* e) {
+ cerr << "Error: " << e << endl;
+ return 3;
+ } catch (...) {
+ cerr << "Unknown error!!!" << endl;
+ return -1;
}
return 0;
}
Los objetivos de BIFE son estos (en orden de importancia):
<ul>
<li>BIFE debe ser rápido.</li>
- <li>BIFE debe ser simple.</li>
+ <li>BIFE debe ser simple.</li>
<li>BIFE debe ser modular.</li>
<li>BIFE debe ser fácil para el creador de contenidos (XML).</li>
</ul>
--- /dev/null
+
+LIBBIFE_DIR=../libbife
+
+DEBUG=-Wall #-g3 -DDEBUG
+CPPFLAGS=-fPIC $(DEBUG)
+LDFLAGS=-L$(LIBBIFE_DIR) -lbife -shared
+
+all: translate.so
+
+translate.o: translate.h translate.cpp
+translate_loader.o: translate_loader.cpp
+
+TARGETS=translate.o translate_loader.o
+translate.so: $(TARGETS)
+ $(CXX) $(DEBUG) $(LDFLAGS) -o translate.so $(TAGETS)
+
+clean:
+ @rm -f *.o translate.so
+
#ifndef BIFE_TRANSLATE_H
#define BIFE_TRANSLATE_H
-#include "fallback.h"
-#include "widget.h"
-#include "hit.h"
-#include "hash.h"
+#include "../libbife/fallback.h"
+#include "../libbife/widget.h"
+#include "../libbife/hit.h"
+#include "../libbife/hash.h"
#include <vector>
#include <string>
--- /dev/null
+// vim: set expandtab tabstop=4 shiftwidth=4:
+
+#include "translate.h"
+#include "../libbife/fallback.h"
+#include "../libbife/widget.h"
+#include "../libbife/hash.h"
+#include <algorithm>
+#include <string>
+
+using bife::Translate;
+using bife::Fallback;
+using bife::Widget;
+using bife::Hash;
+using std::string;
+
+/**
+ * Fallback constructor.
+ *
+ * @param classname Name of the class to construct.
+ * @param widgetname Name of the widget to construct.
+ * @param attrs Widget's attributes.
+ * @return A new Fallback widget.
+ */
+extern "C"
+Fallback* fallback_constructor(const string& classname, const string& widgetname, const Hash& attrs) {
+ string cn = classname;
+ std::transform(cn.begin(), cn.end(), cn.begin(), std::tolower);
+ if (cn == "translate") {
+ return new Translate(widgetname, attrs);
+ } else {
+ return NULL;
+ }
+}
+
+/**
+ * Widget destructor.
+ *
+ * @param w The widget to destroy.
+ */
+extern "C"
+void widget_destructor(Widget* w) {
+ delete w;
+}
+++ /dev/null
-#include "translate.h"
-#include "widget.h"
-#include "hash.h"
-
-using bife::Translate;
-using bife::Widget;
-using bife::Hash;
-using std::string;
-
-// the types of the class factories
-typedef bife::Widget* create_t(const string& name, const Hash&);
-typedef void destroy_t(Widget*);
-
-// the class factories
-extern "C" Widget* create(const string& name, const Hash& attrs) {
- return new Translate(name, attrs);
-}
-extern "C" void destroy(Widget* w) {
- delete w;
-}