]> git.llucax.com Git - software/bife/bife++.git/blob - parser.cpp
Added a typeid() demangle example.
[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         Fallback* fb;
49         try {
50             fb = dynamic_cast<Fallback*>(fbNew(fbClass, attrs));
51             if (!fb) {
52                 throw string("Fallback widget '") + fbClass + " not found!";
53             }
54         } catch (...) {
55             throw fbClass + " is not a Fallback Widget!";
56         }
57         fb->name = name;
58         stack.push(fb);
59     }
60 }
61
62 void Parser::on_end_element(const string& name) {
63 #ifdef DEBUG
64     cerr << "In Parser::on_end_element('" << name << "');" << endl;
65 #endif
66     Widget* cur = stack.top();
67     stack.pop();
68     // If is the last widget, it's the root widget.
69     if (stack.empty()) {
70         root = cur;
71     // If is not the last widget, we add it as content of his parent.
72     } else {
73         Container* par = dynamic_cast<Container*>(stack.top());
74         // If the parent is a Container, we add curent widget as content.
75         if (par) {
76             par->append(cur);
77         // If not, we raise an exception TODO
78         } else {
79             throw "Trying to add content to a non-container widget.";
80         }
81     }
82 }
83
84 void Parser::on_characters(const string& chars) {
85 #ifdef DEBUG
86     cerr << "In Parser::on_characters('" << chars << "');" << endl;
87 #endif
88     if (!stack.empty()) {
89         Container* cur = dynamic_cast<Container*>(stack.top());
90         // If we are in a Container, we add curent string widget as content.
91         if (cur) {
92             cur->append(new String(chars));
93         // If not, we raise an exception TODO
94         } else {
95             throw "Trying to add content to a non-container widget.";
96         }
97     } else {
98         // FIXME - investigar si tiene sentido.
99         throw "Characters with no tags!!!?!?!?!";
100     }
101 }
102
103 void Parser::on_comment(const string& text) {
104 #ifdef DEBUG
105     cerr << "In Parser::on_comment('" << text << "');" << endl;
106 #endif
107 }
108
109 void Parser::on_warning(const string& warn) {
110 #ifdef DEBUG
111     cerr << "In Parser::on_warning('" << warn << "');" << endl;
112 #endif
113 }
114
115 void Parser::on_error(const string& error) {
116 #ifdef DEBUG
117     cerr << "In Parser::on_error('" << error << "');" << endl;
118 #endif
119 }
120
121 void Parser::on_fatal_error(const string& error) {
122 #ifdef DEBUG
123     cerr << "In Parser::on_fatal_error('" << error << "');" << endl;
124 #endif
125 }
126
127 void Parser::on_validity_error(const string& error) {
128 #ifdef DEBUG
129     cerr << "In Parser::on_validity_error('" << error << "');" << endl;
130 #endif
131 }
132
133 void Parser::on_validity_warning(const string& warn) {
134 #ifdef DEBUG
135     cerr << "In Parser::on_validity_warning('" << warn << "');" << endl;
136 #endif
137 }
138
139 /*
140 Parser::Parser(void): fallbackConstructor(NULL), fallbackDestructor(NULL), root(NULL) {
141 #ifdef DEBUG
142     cerr << "In Parser::Parser();" << endl;
143 #endif
144     void* fb = dlopen("./translate.so", RTLD_LAZY); // XXX - así anda: RTLD_NOW | RTLD_GLOBAL);
145     if (!fb) {
146         throw string("No se puede cargar el plug-in: ") + dlerror();
147     }
148     fb_create  = (create_t*)dlsym(fb, "create");
149     fb_destroy = (destroy_t*)dlsym(fb, "destroy");
150     if (!fb_create || !fb_destroy) {
151         throw string("No se puede cargar el creador del plug-in: ") + dlerror();
152     }
153 }
154 */
155
156 Parser::Parser(const string& fallback): fbNew(NULL), fbDel(NULL), root(NULL) {
157 #ifdef DEBUG
158     cerr << "In Parser::Parser(fallback = '" << fallback << "');" << endl;
159 #endif
160     if (!fallback.empty()) {
161         string::size_type pos = fallback.find(".");
162         if (pos == string::npos) {
163             throw string("Fallback module not specified in fallback name: ") + fallback;
164         }
165         fbClass = fallback.substr(pos + 1, fallback.length() - 1);
166         // Opens the fallback module.
167         string modules_dir = "translate";
168         string fb_module = modules_dir + "/" + fallback.substr(0, pos) + ".so";
169         void* dlh = dlopen(fb_module.c_str(), RTLD_LAZY);
170         if (!dlh) {
171             throw string("No se puede cargar el plug-in: ") + dlerror();
172         }
173         fbNew = (Widget::Constructor*)dlsym(dlh, "bife_widget_constructor");
174         fbDel = (Widget::Destructor*)dlsym(dlh, "bife_widget_destructor");
175         if (!fbNew || !fbDel) {
176             throw string("No se puede cargar el creador del plug-in: ") + dlerror();
177         }
178         // TODO - CLOSE dl handler, destroy objects.
179     }
180 }
181
182 Parser::~Parser(void) {
183 #ifdef DEBUG
184     cerr << "In Parser destructor." << endl;
185 #endif
186 }
187 /*
188 Parser::operator string(void) const {
189     stringstream out;
190     return out.str();
191 }
192 */