]> git.llucax.com Git - software/bife/bife++.git/blob - parser.cpp
4f7ed98315af780f3b00f1fd180d525d5147d097
[software/bife/bife++.git] / parser.cpp
1 // vim: set expandtab tabstop=4 shiftwidth=4:
2
3 #include "libbife/widget.h"
4 #include "libbife/container.h"
5 #include "libbife/fallback.h"
6 #include "libbife/string.h"
7 #include "parser.h"
8 //#include <sstream>
9 #include <dlfcn.h>
10
11 //using std::stringstream;
12 using namespace bife;
13
14 #ifdef DEBUG
15 #include <iostream>
16 using std::cerr;
17 using std::endl;
18 #endif
19
20 void Parser::on_start_document(void) {
21 #ifdef DEBUG
22     cerr << "In Parser::on_start_document();" << endl;
23 #endif
24 }
25
26 void Parser::on_end_document(void) {
27 #ifdef DEBUG
28     cerr << "In Parser::on_end_document();" << endl;
29 #endif
30 }
31
32 void Parser::on_start_element(const string& name, const AttributeMap& attrs) {
33 #ifdef DEBUG
34     cerr << "In Parser::on_start_element(name = '" << name << "', attrs = [";
35     if (attrs.size()) {
36         Hash::const_iterator last = attrs.end();
37         last--;
38         for (Hash::const_iterator i = attrs.begin(); i != last; i++) { //last; i++) {
39             cerr << i->first << ": '" << i->second << "', ";
40         }
41         cerr << last->first << ": '" << last->second << "'";
42     }
43     cerr  << "]);" << endl;
44 #endif
45     if (fbClass.empty()) {
46         throw string("Widget '") + name + "' not found and now using a fallback class.";
47     } else {
48         stack.push(fbNew(fbClass, name, attrs));
49     }
50 }
51
52 void Parser::on_end_element(const string& name) {
53 #ifdef DEBUG
54     cerr << "In Parser::on_end_element('" << name << "');" << endl;
55 #endif
56     Widget* cur = stack.top();
57     stack.pop();
58     // If is the last widget, it's the root widget.
59     if (stack.empty()) {
60         root = cur;
61     // If is not the last widget, we add it as content of his parent.
62     } else {
63         Container* par = dynamic_cast<Container*>(stack.top());
64         // If the parent is a Container, we add curent widget as content.
65         if (par) {
66             par->append(cur);
67         // If not, we raise an exception TODO
68         } else {
69             throw "Trying to add content to a non-container widget.";
70         }
71     }
72 }
73
74 void Parser::on_characters(const string& chars) {
75 #ifdef DEBUG
76     cerr << "In Parser::on_characters('" << chars << "');" << endl;
77 #endif
78     if (!stack.empty()) {
79         Container* cur = dynamic_cast<Container*>(stack.top());
80         // If we are in a Container, we add curent string widget as content.
81         if (cur) {
82             cur->append(new String(chars));
83         // If not, we raise an exception TODO
84         } else {
85             throw "Trying to add content to a non-container widget.";
86         }
87     } else {
88         // FIXME - investigar si tiene sentido.
89         throw "Characters with no tags!!!?!?!?!";
90     }
91 }
92
93 void Parser::on_comment(const string& text) {
94 #ifdef DEBUG
95     cerr << "In Parser::on_comment('" << text << "');" << endl;
96 #endif
97 }
98
99 void Parser::on_warning(const string& warn) {
100 #ifdef DEBUG
101     cerr << "In Parser::on_warning('" << warn << "');" << endl;
102 #endif
103 }
104
105 void Parser::on_error(const string& error) {
106 #ifdef DEBUG
107     cerr << "In Parser::on_error('" << error << "');" << endl;
108 #endif
109 }
110
111 void Parser::on_fatal_error(const string& error) {
112 #ifdef DEBUG
113     cerr << "In Parser::on_fatal_error('" << error << "');" << endl;
114 #endif
115 }
116
117 void Parser::on_validity_error(const string& error) {
118 #ifdef DEBUG
119     cerr << "In Parser::on_validity_error('" << error << "');" << endl;
120 #endif
121 }
122
123 void Parser::on_validity_warning(const string& warn) {
124 #ifdef DEBUG
125     cerr << "In Parser::on_validity_warning('" << warn << "');" << endl;
126 #endif
127 }
128
129 /*
130 Parser::Parser(void): fallbackConstructor(NULL), fallbackDestructor(NULL), root(NULL) {
131 #ifdef DEBUG
132     cerr << "In Parser::Parser();" << endl;
133 #endif
134     void* fb = dlopen("./translate.so", RTLD_LAZY); // XXX - así anda: RTLD_NOW | RTLD_GLOBAL);
135     if (!fb) {
136         throw string("No se puede cargar el plug-in: ") + dlerror();
137     }
138     fb_create  = (create_t*)dlsym(fb, "create");
139     fb_destroy = (destroy_t*)dlsym(fb, "destroy");
140     if (!fb_create || !fb_destroy) {
141         throw string("No se puede cargar el creador del plug-in: ") + dlerror();
142     }
143 }
144 */
145
146 Parser::Parser(const string& fallback): fbNew(NULL), fbDel(NULL), root(NULL) {
147 #ifdef DEBUG
148     cerr << "In Parser::Parser(fallback = '" << fallback << "');" << endl;
149 #endif
150     if (!fallback.empty()) {
151         string::size_type pos = fallback.find(".");
152         if (pos == string::npos) {
153             throw string("Fallback module not specified in fallback name: ") + fallback;
154         }
155         fbClass = fallback.substr(pos + 1, fallback.length() - 1);
156         // Opens the fallback module.
157         string modules_dir = "translate";
158         string fb_module = modules_dir + "/" + fallback.substr(0, pos) + ".so";
159         void* dlh = dlopen(fb_module.c_str(), RTLD_LAZY);
160         if (!dlh) {
161             throw string("No se puede cargar el plug-in: ") + dlerror();
162         }
163         fbNew = (Fallback::Constructor*)dlsym(dlh, "fallback_constructor");
164         fbDel = (Widget::Destructor*)dlsym(dlh, "widget_destructor");
165         if (!fbNew || !fbDel) {
166             throw string("No se puede cargar el creador del plug-in: ") + dlerror();
167         }
168         // TODO - CLOSE dl handler, destroy objects.
169     }
170 }
171
172 Parser::~Parser(void) {
173 #ifdef DEBUG
174     cerr << "In Parser destructor." << endl;
175 #endif
176 }
177 /*
178 Parser::operator string(void) const {
179     stringstream out;
180     return out.str();
181 }
182 */