seems to work
This commit is contained in:
parent
2c44efeb2f
commit
d7d6ae1479
47 changed files with 533 additions and 38 deletions
290
bindgen.cxx
290
bindgen.cxx
|
|
@ -16,16 +16,22 @@ struct typeinfo {
|
|||
struct property {
|
||||
typeinfo type;
|
||||
int common;
|
||||
};
|
||||
|
||||
struct handler {
|
||||
int common;
|
||||
int has_arg;
|
||||
typeinfo arg_type;
|
||||
};
|
||||
|
||||
std::map<std::string, std::ofstream> files;
|
||||
|
||||
std::map<std::string, property> props;
|
||||
std::map<std::string, handler> handlers;
|
||||
|
||||
std::locale locale;
|
||||
|
||||
static std::string get_ctype(typeinfo type, int name = 1) {
|
||||
static std::string get_ctype(typeinfo type, int name = 1, int do_ptr = 1) {
|
||||
std::string ret = "";
|
||||
|
||||
if(type.type == "integer") {
|
||||
|
|
@ -40,7 +46,7 @@ static std::string get_ctype(typeinfo type, int name = 1) {
|
|||
ret += type.struct_name;
|
||||
}
|
||||
|
||||
if(type.pointer) ret += "*";
|
||||
if(do_ptr && type.pointer) ret += "*";
|
||||
|
||||
if(name && type.name != "") {
|
||||
ret += " " + type.name;
|
||||
|
|
@ -93,26 +99,19 @@ static typeinfo xml_to_type(xl_node_t* node) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
static std::string first_upper(std::string str) {
|
||||
static std::string upperfirst(std::string str) {
|
||||
return uppercase(str.substr(0, 1)) + str.substr(1);
|
||||
}
|
||||
|
||||
static void scan_property(xl_node_t* node) {
|
||||
property prop;
|
||||
char* s;
|
||||
xl_node_t* child = node->first_child;
|
||||
property prop;
|
||||
char* s;
|
||||
|
||||
if(node->type != XL_NODE_NODE) return;
|
||||
|
||||
prop.type = xml_to_type(node);
|
||||
prop.common = ATTR_TO_BOOL(node, "common");
|
||||
|
||||
while(child != NULL) {
|
||||
if(child->type == XL_NODE_NODE) prop.arg_type = xml_to_type(child);
|
||||
|
||||
child = child->next;
|
||||
}
|
||||
|
||||
props[xl_get_attribute(node, "name")] = prop;
|
||||
}
|
||||
|
||||
|
|
@ -126,38 +125,43 @@ static void scan_properties(xl_node_t* node) {
|
|||
}
|
||||
}
|
||||
|
||||
static void scan_handler(xl_node_t* node) {
|
||||
handler handl;
|
||||
char* s;
|
||||
xl_node_t* child = node->first_child;
|
||||
|
||||
if(node->type != XL_NODE_NODE) return;
|
||||
|
||||
handl.common = ATTR_TO_BOOL(node, "common");
|
||||
handl.has_arg = 0;
|
||||
|
||||
while(child != NULL) {
|
||||
if(child->type == XL_NODE_NODE) {
|
||||
handl.has_arg = 1;
|
||||
handl.arg_type = xml_to_type(child);
|
||||
}
|
||||
|
||||
child = child->next;
|
||||
}
|
||||
|
||||
handlers[xl_get_attribute(node, "name")] = handl;
|
||||
}
|
||||
|
||||
static void scan_handlers(xl_node_t* node) {
|
||||
xl_node_t* child = node->first_child;
|
||||
|
||||
while(child != NULL) {
|
||||
scan_handler(child);
|
||||
|
||||
child = child->next;
|
||||
}
|
||||
}
|
||||
|
||||
static std::string widget_property_header(std::string name, std::string indent = "") {
|
||||
std::stringstream strm;
|
||||
|
||||
strm << indent + get_ctype(props[name].type, 0) + " Get" + first_upper(name) + "();" << std::endl;
|
||||
strm << indent + "void Set" + first_upper(name) + "(" + get_ctype(props[name].type, 0) + " value);" << std::endl;
|
||||
|
||||
return strm.str();
|
||||
}
|
||||
|
||||
static std::string widget_property_source(std::string widget, std::string name) {
|
||||
std::stringstream strm;
|
||||
|
||||
strm << get_ctype(props[name].type, 0) + " MwCXX::" + widget + "::Get" + first_upper(name) + "() {" << std::endl;
|
||||
strm << " return (" + get_ctype(props[name].type, 0) + ")MwGet" + get_type(props[name].type) + "(this->widget, MwN" + name + ");" << std::endl;
|
||||
strm << "}" << std::endl;
|
||||
strm << std::endl;
|
||||
strm << "void MwCXX::" + widget + "::Set" + first_upper(name) + "(" + get_ctype(props[name].type, 0) + " value) {" << std::endl;
|
||||
|
||||
if(props[name].type.type == "string") {
|
||||
strm << "#ifndef MWCXX_USE_C_STRING" << std::endl;
|
||||
strm << " MwSetText(this->widget, MwN" + name + ", value.c_str());" << std::endl;
|
||||
strm << "#else" << std::endl;
|
||||
}
|
||||
|
||||
strm << " MwSet" + get_type(props[name].type) + "(this->widget, MwN" + name + ", (" + get_ctype(props[name].type, 0) + ")value);" << std::endl;
|
||||
|
||||
if(props[name].type.type == "string") {
|
||||
strm << "#endif" << std::endl;
|
||||
}
|
||||
|
||||
strm << "}" << std::endl;
|
||||
strm << std::endl;
|
||||
strm << indent + get_ctype(props[name].type, 0) + " Get" + upperfirst(name) + "();" << std::endl;
|
||||
strm << indent + "void Set" + upperfirst(name) + "(" + get_ctype(props[name].type, 0) + " value);" << std::endl;
|
||||
|
||||
return strm.str();
|
||||
}
|
||||
|
|
@ -183,20 +187,119 @@ static std::string scan_widget_properties_header(xl_node_t* node, std::string in
|
|||
return r;
|
||||
}
|
||||
|
||||
static std::string scan_widget_property_source(xl_node_t* node, std::string name) {
|
||||
static std::string widget_property_source(std::string widget, std::string name) {
|
||||
std::stringstream strm;
|
||||
|
||||
strm << get_ctype(props[name].type, 0) + " MwCXX::" + widget + "::Get" + upperfirst(name) + "() {" << std::endl;
|
||||
strm << " return (" + get_ctype(props[name].type, 0) + ")MwGet" + get_type(props[name].type) + "(this->widget, MwN" + name + ");" << std::endl;
|
||||
strm << "}" << std::endl;
|
||||
strm << std::endl;
|
||||
strm << "void MwCXX::" + widget + "::Set" + upperfirst(name) + "(" + get_ctype(props[name].type, 0) + " value) {" << std::endl;
|
||||
|
||||
if(props[name].type.type == "string") {
|
||||
strm << "#ifndef MWCXX_USE_C_STRING" << std::endl;
|
||||
strm << " MwSetText(this->widget, MwN" + name + ", value.c_str());" << std::endl;
|
||||
strm << "#else" << std::endl;
|
||||
}
|
||||
|
||||
strm << " MwSet" + get_type(props[name].type) + "(this->widget, MwN" + name + ", (" + get_ctype(props[name].type, 0) + ")value);" << std::endl;
|
||||
|
||||
if(props[name].type.type == "string") {
|
||||
strm << "#endif" << std::endl;
|
||||
}
|
||||
|
||||
strm << "}" << std::endl;
|
||||
strm << std::endl;
|
||||
|
||||
return strm.str();
|
||||
}
|
||||
|
||||
static std::string scan_widget_property_source(xl_node_t* node, std::string widget) {
|
||||
xl_node_t* child = node->first_child;
|
||||
|
||||
if(node->type != XL_NODE_NODE) return "";
|
||||
|
||||
return widget_property_source(name, xl_get_attribute(node, "name"));
|
||||
return widget_property_source(widget, xl_get_attribute(node, "name"));
|
||||
}
|
||||
|
||||
static std::string scan_widget_properties_source(xl_node_t* node, std::string name) {
|
||||
static std::string scan_widget_properties_source(xl_node_t* node, std::string widget) {
|
||||
std::string r = "";
|
||||
xl_node_t* child = node->first_child;
|
||||
|
||||
while(child != NULL) {
|
||||
r += scan_widget_property_source(child, name);
|
||||
r += scan_widget_property_source(child, widget);
|
||||
|
||||
child = child->next;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static std::string widget_handler_header(std::string name, std::string indent = "") {
|
||||
std::stringstream strm;
|
||||
|
||||
strm << indent + "virtual void On" + upperfirst(name) + "(" + (handlers[name].has_arg ? (get_ctype(handlers[name].arg_type, 0, 0) + " value") : "") + ") {};" << std::endl;
|
||||
|
||||
return strm.str();
|
||||
}
|
||||
|
||||
static std::string scan_widget_handler_header(xl_node_t* node, std::string indent) {
|
||||
xl_node_t* child = node->first_child;
|
||||
|
||||
if(node->type != XL_NODE_NODE) return "";
|
||||
|
||||
return widget_handler_header(xl_get_attribute(node, "name"), indent);
|
||||
}
|
||||
|
||||
static std::string scan_widget_handlers_header(xl_node_t* node, std::string indent) {
|
||||
std::string r = "";
|
||||
xl_node_t* child = node->first_child;
|
||||
|
||||
while(child != NULL) {
|
||||
r += scan_widget_handler_header(child, indent);
|
||||
|
||||
child = child->next;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static std::string widget_handler_source(std::string widget, std::string name) {
|
||||
std::stringstream strm;
|
||||
std::string cast = "";
|
||||
|
||||
if(handlers[name].has_arg) {
|
||||
cast = "(" + get_ctype(handlers[name].arg_type, 0) + ")";
|
||||
|
||||
if(handlers[name].arg_type.pointer) cast = "*" + cast;
|
||||
|
||||
if(handlers[name].arg_type.type == "string") cast += "(char*)";
|
||||
|
||||
cast += "call";
|
||||
}
|
||||
|
||||
strm << "static void __On" + upperfirst(name) + "(MwWidget handle, void* user, void* call) {" << std::endl;
|
||||
strm << " ((MwCXX::" + widget + "*)user)->On" + upperfirst(name) + "(" + cast + ");" << std::endl;
|
||||
strm << "}" << std::endl;
|
||||
strm << std::endl;
|
||||
|
||||
return strm.str();
|
||||
}
|
||||
|
||||
static std::string scan_widget_handler_source(xl_node_t* node, std::string widget) {
|
||||
xl_node_t* child = node->first_child;
|
||||
|
||||
if(node->type != XL_NODE_NODE) return "";
|
||||
|
||||
return widget_handler_source(widget, xl_get_attribute(node, "name"));
|
||||
}
|
||||
|
||||
static std::string scan_widget_handlers_source(xl_node_t* node, std::string widget) {
|
||||
std::string r = "";
|
||||
xl_node_t* child = node->first_child;
|
||||
|
||||
while(child != NULL) {
|
||||
r += scan_widget_handler_source(child, widget);
|
||||
|
||||
child = child->next;
|
||||
}
|
||||
|
|
@ -206,12 +309,15 @@ static std::string scan_widget_properties_source(xl_node_t* node, std::string na
|
|||
|
||||
static void scan_widget(xl_node_t* node) {
|
||||
std::string name;
|
||||
xl_node_t** nodes;
|
||||
xl_node_t** p_nodes;
|
||||
xl_node_t** h_nodes;
|
||||
xl_node_t* child;
|
||||
int i;
|
||||
|
||||
if(node->type != XL_NODE_NODE) return;
|
||||
|
||||
nodes = xl_get_path(node, "properties");
|
||||
p_nodes = xl_get_path(node, "properties");
|
||||
h_nodes = xl_get_path(node, "handlers");
|
||||
|
||||
name = xl_get_attribute(node, "name");
|
||||
|
||||
|
|
@ -230,15 +336,29 @@ static void scan_widget(xl_node_t* node) {
|
|||
|
||||
OFS << "namespace MwCXX {" << std::endl;
|
||||
OFS << " class " + name + " : public MwCXX::Base {" << std::endl;
|
||||
OFS << " protected:" << std::endl;
|
||||
OFS << " virtual void RegisterHandlers();" << std::endl;
|
||||
OFS << std::endl;
|
||||
OFS << " public:" << std::endl;
|
||||
OFS << " " + name + "(MwWidget widget);" << std::endl;
|
||||
OFS << " " + name + "(MwCXX::String name, MwCXX::Base* parent, int x, int y, unsigned int width, unsigned int height);" << std::endl;
|
||||
|
||||
if(nodes != NULL) {
|
||||
if(p_nodes != NULL) {
|
||||
std::string r = "";
|
||||
|
||||
for(i = 0; nodes[i] != NULL; i++) {
|
||||
r += scan_widget_properties_header(nodes[i], "\t\t");
|
||||
for(i = 0; p_nodes[i] != NULL; i++) {
|
||||
r += scan_widget_properties_header(p_nodes[i], "\t\t");
|
||||
}
|
||||
|
||||
if(r != "") OFS << std::endl
|
||||
<< r;
|
||||
}
|
||||
|
||||
if(h_nodes != NULL) {
|
||||
std::string r = "";
|
||||
|
||||
for(i = 0; h_nodes[i] != NULL; i++) {
|
||||
r += scan_widget_handlers_header(h_nodes[i], "\t\t");
|
||||
}
|
||||
|
||||
if(r != "") OFS << std::endl
|
||||
|
|
@ -263,22 +383,47 @@ static void scan_widget(xl_node_t* node) {
|
|||
OFS << std::endl;
|
||||
|
||||
OFS << "MwCXX::" + name + "::" + name + "(MwWidget widget) : MwCXX::Base(widget) {" << std::endl;
|
||||
OFS << " this->RegisterHandlers();" << std::endl;
|
||||
OFS << "}" << std::endl;
|
||||
OFS << std::endl;
|
||||
|
||||
OFS << "MwCXX::" + name + "::" + name + "(MwCXX::String name, MwCXX::Base* parent, int x, int y, unsigned int width, unsigned int height) : MwCXX::Base(Mw" + name + "Class, name, parent, x, y, width, height) {" << std::endl;
|
||||
OFS << " this->RegisterHandlers();" << std::endl;
|
||||
OFS << "}" << std::endl;
|
||||
OFS << std::endl;
|
||||
|
||||
if(nodes != NULL) {
|
||||
for(i = 0; nodes[i] != NULL; i++) {
|
||||
OFS << scan_widget_properties_source(nodes[i], name);
|
||||
if(p_nodes != NULL) {
|
||||
for(i = 0; p_nodes[i] != NULL; i++) {
|
||||
OFS << scan_widget_properties_source(p_nodes[i], name);
|
||||
}
|
||||
}
|
||||
|
||||
if(h_nodes != NULL) {
|
||||
for(i = 0; h_nodes[i] != NULL; i++) {
|
||||
OFS << scan_widget_handlers_source(h_nodes[i], name);
|
||||
}
|
||||
}
|
||||
|
||||
OFS << "void MwCXX::" + name + "::RegisterHandlers() {" << std::endl;
|
||||
if(h_nodes != NULL) {
|
||||
for(i = 0; h_nodes[i] != NULL; i++) {
|
||||
for(child = h_nodes[i]->first_child; child != NULL; child = child->next) {
|
||||
std::string hname;
|
||||
|
||||
if(child->type != XL_NODE_NODE) continue;
|
||||
|
||||
hname = xl_get_attribute(child, "name");
|
||||
|
||||
OFS << " MwAddUserHandler(this->widget, MwN" + hname + "Handler, __On" + upperfirst(hname) + ", (void*)this);" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
OFS << "}" << std::endl;
|
||||
|
||||
#undef OFS
|
||||
|
||||
if(nodes != NULL) free(nodes);
|
||||
if(p_nodes != NULL) free(p_nodes);
|
||||
if(h_nodes != NULL) free(h_nodes);
|
||||
|
||||
files["objs"] << " src/widget/" + lowercase(name) + ".o";
|
||||
}
|
||||
|
|
@ -294,16 +439,26 @@ static void scan_widgets(xl_node_t* node) {
|
|||
}
|
||||
|
||||
static void base_widget() {
|
||||
std::string r = "";
|
||||
int f;
|
||||
|
||||
#define OFS files["WBaseAuto.h"]
|
||||
|
||||
OFS = std::ofstream("include/MwCXX/Widget/BaseAuto.h");
|
||||
|
||||
f = 0;
|
||||
for(auto p = props.begin(); p != props.end(); p++) {
|
||||
if(!p->second.common) continue;
|
||||
|
||||
OFS << widget_property_header(p->first);
|
||||
f = 1;
|
||||
}
|
||||
|
||||
if(f) OFS << std::endl;
|
||||
|
||||
for(auto p = handlers.begin(); p != handlers.end(); p++) {
|
||||
if(!p->second.common) continue;
|
||||
|
||||
OFS << widget_handler_header(p->first);
|
||||
}
|
||||
|
||||
#undef OFS
|
||||
|
|
@ -317,11 +472,22 @@ static void base_widget() {
|
|||
for(auto p = props.begin(); p != props.end(); p++) {
|
||||
if(!p->second.common) continue;
|
||||
|
||||
r += widget_property_source("Base", p->first);
|
||||
OFS << widget_property_source("Base", p->first);
|
||||
}
|
||||
|
||||
if(r != "") OFS << std::endl
|
||||
<< r;
|
||||
for(auto h = handlers.begin(); h != handlers.end(); h++) {
|
||||
if(!h->second.common) continue;
|
||||
|
||||
OFS << widget_handler_source("Base", h->first);
|
||||
}
|
||||
|
||||
OFS << "void MwCXX::Base::RegisterHandlers() {" << std::endl;
|
||||
for(auto h = handlers.begin(); h != handlers.end(); h++) {
|
||||
if(!h->second.common) continue;
|
||||
|
||||
OFS << " MwAddUserHandler(this->widget, MwN" + h->first + "Handler, __On" + upperfirst(h->first) + ", (void*)this);" << std::endl;
|
||||
}
|
||||
OFS << "}" << std::endl;
|
||||
|
||||
#undef OFS
|
||||
|
||||
|
|
@ -359,6 +525,14 @@ int main(int argc, char** argv) {
|
|||
free(nodes);
|
||||
}
|
||||
|
||||
if((nodes = xl_get_path(h->root, "handlers")) != NULL) {
|
||||
for(int i = 0; nodes[i] != NULL; i++) {
|
||||
scan_handlers(nodes[i]);
|
||||
}
|
||||
|
||||
free(nodes);
|
||||
}
|
||||
|
||||
base_widget();
|
||||
|
||||
if((nodes = xl_get_path(h->root, "widgets")) != NULL) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue