2026-04-16 15:01:47 +09:00
# include <xemil.h>
# include <map>
# include <string>
# include <fstream>
2026-04-17 19:42:14 +09:00
# include <sstream>
# include <locale>
2026-04-17 22:44:19 +09:00
# include <iostream>
2026-04-17 19:42:14 +09:00
struct typeinfo {
2026-04-17 21:26:28 +09:00
std : : string type ;
std : : string name ;
std : : string struct_name ;
2026-04-18 01:05:20 +09:00
std : : string widget_type ;
2026-04-17 21:26:28 +09:00
int pointer ;
2026-04-19 06:35:19 +09:00
int unsigned_num ;
2026-04-17 19:42:14 +09:00
} ;
2026-04-16 15:01:47 +09:00
struct property {
2026-04-17 21:26:28 +09:00
typeinfo type ;
int common ;
2026-04-17 22:25:28 +09:00
} ;
struct handler {
int common ;
int has_arg ;
2026-04-17 21:26:28 +09:00
typeinfo arg_type ;
2026-04-16 15:01:47 +09:00
} ;
2026-04-17 19:42:14 +09:00
std : : map < std : : string , std : : ofstream > files ;
2026-04-16 15:01:47 +09:00
std : : map < std : : string , property > props ;
2026-04-17 22:25:28 +09:00
std : : map < std : : string , handler > handlers ;
2026-04-16 15:01:47 +09:00
2026-04-17 19:42:14 +09:00
std : : locale locale ;
2026-04-17 22:25:28 +09:00
static std : : string get_ctype ( typeinfo type , int name = 1 , int do_ptr = 1 ) {
2026-04-17 19:42:14 +09:00
std : : string ret = " " ;
if ( type . type = = " integer " ) {
ret + = " int " ;
2026-04-19 06:35:19 +09:00
} else if ( type . type = = " short " ) {
ret + = " short " ;
2026-09-14 03:22:51 +09:00
} else if ( type . type = = " double " ) {
ret + = " double " ;
2026-04-17 19:42:14 +09:00
} else if ( type . type = = " string " ) {
ret + = " MwCXX::String " ;
} else if ( type . type = = " pixmap " ) {
ret + = " MwLLPixmap " ;
} else if ( type . type = = " pointer " ) {
ret + = " void* " ;
} else if ( type . type = = " struct " ) {
ret + = type . struct_name ;
2026-04-18 01:05:20 +09:00
} else if ( type . type = = " widget " ) {
2026-04-18 02:31:46 +09:00
if ( type . widget_type = = " " ) {
2026-04-18 01:05:20 +09:00
ret + = " MwCXX::Base* " ;
2026-04-18 02:31:46 +09:00
} else {
2026-04-18 01:05:20 +09:00
ret + = " MwCXX:: " + type . widget_type + " * " ;
}
2026-04-19 20:18:43 +09:00
} else if ( type . type = = " class " ) {
2026-04-19 12:08:21 +09:00
ret + = " MwClass " ;
2026-04-17 19:42:14 +09:00
}
2026-04-19 06:35:19 +09:00
if ( type . unsigned_num ) ret = " unsigned " + ret ;
2026-04-17 22:25:28 +09:00
if ( do_ptr & & type . pointer ) ret + = " * " ;
2026-04-17 19:42:14 +09:00
if ( name & & type . name ! = " " ) {
ret + = " " + type . name ;
}
return ret ;
}
static std : : string get_type ( typeinfo type ) {
if ( type . type = = " integer " ) {
return " Integer " ;
} else if ( type . type = = " string " ) {
2026-09-27 07:21:54 +09:00
return " String " ;
2026-04-17 19:42:14 +09:00
}
2026-09-27 07:21:54 +09:00
return " Pointer " ;
2026-04-17 19:42:14 +09:00
}
static std : : string uppercase ( std : : string str ) {
std : : string r = str ;
for ( int i = 0 ; i < r . size ( ) ; i + + ) {
r [ i ] = std : : toupper ( r [ i ] , locale ) ;
}
return r ;
}
static std : : string lowercase ( std : : string str ) {
std : : string r = str ;
for ( int i = 0 ; i < r . size ( ) ; i + + ) {
r [ i ] = std : : tolower ( r [ i ] , locale ) ;
}
2026-04-16 15:01:47 +09:00
2026-04-17 19:42:14 +09:00
return r ;
2026-04-16 15:01:47 +09:00
}
2026-04-17 19:42:14 +09:00
# define ATTR_TO_BOOL(node, x) ((s = xl_get_attribute(node, (x))) != NULL) && (strcmp(s, "no") != 0);
static typeinfo xml_to_type ( xl_node_t * node ) {
char * s ;
typeinfo ret ;
2026-04-19 06:35:19 +09:00
ret . type = node - > name ;
ret . name = ( ( s = xl_get_attribute ( node , " name " ) ) ! = NULL ) ? s : " " ;
ret . struct_name = ( ( s = xl_get_attribute ( node , " defname " ) ) ! = NULL ) ? s : " " ;
ret . widget_type = ( ( s = xl_get_attribute ( node , " type " ) ) ! = NULL ) ? s : " " ;
ret . pointer = ATTR_TO_BOOL ( node , " pointer " ) ;
ret . unsigned_num = ATTR_TO_BOOL ( node , " unsigned " ) ;
2026-04-17 19:42:14 +09:00
return ret ;
}
2026-04-17 22:25:28 +09:00
static std : : string upperfirst ( std : : string str ) {
2026-04-17 19:42:14 +09:00
return uppercase ( str . substr ( 0 , 1 ) ) + str . substr ( 1 ) ;
}
static void scan_property ( xl_node_t * node ) {
2026-04-17 22:25:28 +09:00
property prop ;
char * s ;
2026-04-16 15:01:47 +09:00
if ( node - > type ! = XL_NODE_NODE ) return ;
2026-04-17 19:42:14 +09:00
prop . type = xml_to_type ( node ) ;
prop . common = ATTR_TO_BOOL ( node , " common " ) ;
2026-04-17 22:25:28 +09:00
props [ xl_get_attribute ( node , " name " ) ] = prop ;
}
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 ;
2026-04-16 15:01:47 +09:00
}
2026-04-17 19:42:14 +09:00
static std : : string widget_property_header ( std : : string name , std : : string indent = " " ) {
std : : stringstream strm ;
2026-04-17 22:25:28 +09:00
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 ;
2026-04-17 19:42:14 +09:00
return strm . str ( ) ;
}
2026-04-17 22:25:28 +09:00
static std : : string scan_widget_property_header ( xl_node_t * node , std : : string indent ) {
xl_node_t * child = node - > first_child ;
if ( node - > type ! = XL_NODE_NODE ) return " " ;
return widget_property_header ( xl_get_attribute ( node , " name " ) , indent ) ;
}
2026-04-17 19:42:14 +09:00
static std : : string widget_property_source ( std : : string widget , std : : string name ) {
std : : stringstream strm ;
2026-04-17 22:25:28 +09:00
strm < < get_ctype ( props [ name ] . type , 0 ) + " MwCXX:: " + widget + " ::Get " + upperfirst ( name ) + " () { " < < std : : endl ;
2026-04-17 19:42:14 +09:00
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 ;
2026-04-17 22:25:28 +09:00
strm < < " void MwCXX:: " + widget + " ::Set " + upperfirst ( name ) + " ( " + get_ctype ( props [ name ] . type , 0 ) + " value) { " < < std : : endl ;
2026-04-17 19:42:14 +09:00
if ( props [ name ] . type . type = = " string " ) {
strm < < " #ifndef MWCXX_USE_C_STRING " < < std : : endl ;
2026-09-27 07:21:54 +09:00
strm < < " MwSetString(this->widget, MwN " + name + " , value.c_str()); " < < std : : endl ;
2026-04-17 19:42:14 +09:00
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 ( ) ;
}
2026-04-17 22:25:28 +09:00
static std : : string scan_widget_property_source ( xl_node_t * node , std : : string widget ) {
2026-04-17 19:42:14 +09:00
xl_node_t * child = node - > first_child ;
if ( node - > type ! = XL_NODE_NODE ) return " " ;
2026-04-17 22:25:28 +09:00
return widget_property_source ( widget , xl_get_attribute ( node , " name " ) ) ;
2026-04-17 19:42:14 +09:00
}
2026-04-18 02:31:46 +09:00
static std : : string widget_handler_header ( std : : string widget , std : : string name , std : : string indent = " " , int func = 1 ) {
2026-04-17 22:25:28 +09:00
std : : stringstream strm ;
2026-04-18 02:31:46 +09:00
std : : string pre = " " ;
strm < < indent ;
if ( func ) {
strm < < " virtual void On " + upperfirst ( name ) ;
} else {
strm < < " void (* " + upperfirst ( name ) + " Handler) " ;
pre + = " MwCXX:: " + widget + " * widget " ;
if ( handlers [ name ] . has_arg ) pre + = " , " ;
}
strm < < " ( " + pre + ( handlers [ name ] . has_arg ? ( get_ctype ( handlers [ name ] . arg_type , 0 , 0 ) + " value " ) : " " ) + " ) " ;
if ( func ) strm < < " {} " ;
2026-04-17 22:25:28 +09:00
2026-04-18 02:31:46 +09:00
strm < < " ; " < < std : : endl ;
2026-04-17 22:25:28 +09:00
return strm . str ( ) ;
}
2026-04-18 02:31:46 +09:00
static std : : string scan_widget_handler_header ( xl_node_t * node , std : : string widget , std : : string indent , int func = 1 ) {
2026-04-17 19:42:14 +09:00
xl_node_t * child = node - > first_child ;
if ( node - > type ! = XL_NODE_NODE ) return " " ;
2026-04-18 02:31:46 +09:00
return widget_handler_header ( widget , xl_get_attribute ( node , " name " ) , indent , func ) ;
2026-04-17 19:42:14 +09:00
}
2026-04-17 22:25:28 +09:00
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 ;
2026-04-18 02:31:46 +09:00
strm < < " if(((MwCXX:: " + widget + " *)user)-> " + upperfirst ( name ) + " Handler != NULL) ((MwCXX:: " + widget + " *)user)-> " + upperfirst ( name ) + " Handler((MwCXX:: " + widget + " *)user " + ( handlers [ name ] . has_arg ? ( " , " + cast ) : " " ) + " ); " < < std : : endl ;
2026-04-17 22:25:28 +09:00
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 " ) ) ;
}
2026-04-20 05:29:42 +09:00
static std : : string widget_function_header ( xl_node_t * node , std : : string indent , std : : string prefix = " " , int func = 1 , xl_node_t * * pret = NULL , xl_node_t * * pargs = NULL ) {
std : : stringstream strm ;
xl_node_t * child ;
xl_node_t * ret = NULL ;
xl_node_t * args = NULL ;
int c = 0 ;
if ( node - > type ! = XL_NODE_NODE ) return " " ;
for ( child = node - > first_child ; child ! = NULL ; child = child - > next ) {
if ( child - > type ! = XL_NODE_NODE ) continue ;
if ( strcmp ( child - > name , " return " ) = = 0 ) {
for ( ret = child - > first_child ; ret ! = NULL ; ret = ret - > next ) {
if ( ret - > type = = XL_NODE_NODE ) break ;
}
} else if ( strcmp ( child - > name , " arguments " ) = = 0 ) {
args = child - > first_child ;
}
}
if ( pret ! = NULL ) * pret = ret ;
if ( pargs ! = NULL ) * pargs = args ;
strm < < indent ;
if ( ret = = NULL ) {
strm < < " void " ;
} else {
strm < < get_ctype ( xml_to_type ( ret ) ) + " " ;
}
strm < < prefix + std : : string ( xl_get_attribute ( node , " name " ) ) + " ( " ;
c = 0 ;
for ( child = args ; child ! = NULL ; child = child - > next ) {
if ( child - > type ! = XL_NODE_NODE ) continue ;
if ( c > 0 ) strm < < " , " ;
strm < < get_ctype ( xml_to_type ( child ) ) ;
c + + ;
}
strm < < " ) " ;
if ( func ) strm < < " ; " ;
strm < < std : : endl ;
return strm . str ( ) ;
}
static std : : string widget_function_source ( xl_node_t * node , std : : string widget ) {
std : : stringstream strm ;
xl_node_t * child ;
std : : string rettype = " " ;
xl_node_t * ret = NULL ;
xl_node_t * args = NULL ;
typeinfo retti ;
strm < < widget_function_header ( node , " " , " MwCXX:: " + widget + " :: " , 0 , & ret , & args ) + " { " < < std : : endl ;
if ( ret ! = NULL ) {
retti = xml_to_type ( ret ) ;
rettype = get_ctype ( retti , 0 , 0 ) ;
if ( rettype = = " MwCXX::String " ) rettype = " char* " ;
if ( retti . pointer ) rettype + = " * " ;
}
if ( rettype ! = " " ) {
strm < < " " + rettype + " out; " < < std : : endl ;
strm < < std : : endl ;
}
strm < < " MwVaWidgetExecute(this->widget, \" mw " + widget + std : : string ( xl_get_attribute ( node , " name " ) ) + " \" , " ;
if ( rettype = = " " ) {
strm < < " NULL " ;
} else {
strm < < " &out " ;
}
for ( child = args ; child ! = NULL ; child = child - > next ) {
typeinfo ti = xml_to_type ( child ) ;
if ( ti . type = = " string " ) {
strm < < " , " < < std : : endl ;
strm < < " #ifdef MWCXX_USE_C_STRING " < < std : : endl ;
strm < < " " + ti . name < < std : : endl ;
strm < < " #else " < < std : : endl ;
strm < < " " + ti . name + " .c_str() " < < std : : endl ;
strm < < " #endif " < < std : : endl ;
} else {
strm < < " , " + ti . name ;
}
}
strm < < " ); " < < std : : endl ;
if ( rettype ! = " " ) {
strm < < std : : endl ;
if ( retti . type = = " string " ) {
strm < < " #ifdef MWCXX_USE_C_STRING " < < std : : endl ;
strm < < " return out; " < < std : : endl ;
strm < < " #else " < < std : : endl ;
strm < < " return MwCXX::String(out); " < < std : : endl ;
strm < < " #endif " < < std : : endl ;
} else {
strm < < " return out; " < < std : : endl ;
}
}
strm < < " } " < < std : : endl ;
strm < < std : : endl ;
return strm . str ( ) ;
}
2026-04-17 19:42:14 +09:00
static void scan_widget ( xl_node_t * node ) {
std : : string name ;
2026-04-17 22:25:28 +09:00
xl_node_t * * p_nodes ;
xl_node_t * * h_nodes ;
2026-04-20 05:29:42 +09:00
xl_node_t * * f_nodes ;
2026-04-17 19:42:14 +09:00
if ( node - > type ! = XL_NODE_NODE ) return ;
2026-04-17 22:25:28 +09:00
p_nodes = xl_get_path ( node , " properties " ) ;
h_nodes = xl_get_path ( node , " handlers " ) ;
2026-04-20 05:29:42 +09:00
f_nodes = xl_get_path ( node , " functions " ) ;
2026-04-17 19:42:14 +09:00
name = xl_get_attribute ( node , " name " ) ;
# define OFS files["W" + name + ".h"]
OFS = std : : ofstream ( " include/MwCXX/Widget/ " + name + " .h " ) ;
OFS < < " #ifndef __MWCXX_WIDGET_ " + uppercase ( name ) + " _H__ " < < std : : endl ;
OFS < < " #define __MWCXX_WIDGET_ " + uppercase ( name ) + " _H__ " < < std : : endl ;
OFS < < std : : endl ;
OFS < < " #include <MwCXX/MachDep.h> " < < std : : endl ;
OFS < < " #include <MwCXX/Widget/Base.h> " < < std : : endl ;
OFS < < std : : endl ;
OFS < < " #include <Mw/Widget/ " + name + " .h> " < < std : : endl ;
OFS < < std : : endl ;
OFS < < " namespace MwCXX { " < < std : : endl ;
OFS < < " class " + name + " : public MwCXX::Base { " < < std : : endl ;
2026-04-17 22:25:28 +09:00
OFS < < " protected: " < < std : : endl ;
OFS < < " virtual void RegisterHandlers(); " < < std : : endl ;
OFS < < std : : endl ;
2026-04-17 21:26:28 +09:00
OFS < < " public: " < < std : : endl ;
2026-04-18 01:05:20 +09:00
OFS < < " " + name + " (MwWidget widget, MwCXX::Base* parent = NULL); " < < std : : endl ;
2026-04-17 21:26:28 +09:00
OFS < < " " + name + " (MwCXX::String name, MwCXX::Base* parent, int x, int y, unsigned int width, unsigned int height); " < < std : : endl ;
2026-04-17 19:42:14 +09:00
2026-04-17 22:25:28 +09:00
if ( p_nodes ! = NULL ) {
2026-04-18 02:31:46 +09:00
std : : string r ;
2026-04-17 19:42:14 +09:00
2026-04-18 02:31:46 +09:00
r = " " ;
2026-04-18 01:05:20 +09:00
for ( int i = 0 ; p_nodes [ i ] ! = NULL ; i + + ) {
2026-04-18 02:31:46 +09:00
for ( xl_node_t * child = p_nodes [ i ] - > first_child ; child ! = NULL ; child = child - > next ) {
2026-04-18 01:05:20 +09:00
if ( child - > type ! = XL_NODE_NODE ) continue ;
r + = scan_widget_property_header ( child , " \t \t " ) ;
}
2026-04-17 22:25:28 +09:00
}
if ( r ! = " " ) OFS < < std : : endl
< < r ;
}
if ( h_nodes ! = NULL ) {
2026-04-18 02:31:46 +09:00
std : : string r ;
2026-04-17 22:25:28 +09:00
2026-04-18 02:31:46 +09:00
r = " " ;
2026-04-18 01:05:20 +09:00
for ( int i = 0 ; h_nodes [ i ] ! = NULL ; i + + ) {
2026-04-18 02:31:46 +09:00
for ( xl_node_t * child = h_nodes [ i ] - > first_child ; child ! = NULL ; child = child - > next ) {
2026-04-18 01:05:20 +09:00
if ( child - > type ! = XL_NODE_NODE ) continue ;
2026-04-18 02:31:46 +09:00
r + = scan_widget_handler_header ( child , name , " \t \t " ) ;
2026-04-18 01:05:20 +09:00
}
2026-04-17 19:42:14 +09:00
}
2026-04-18 02:31:46 +09:00
if ( r ! = " " ) OFS < < std : : endl
< < r ;
2026-04-17 19:42:14 +09:00
2026-04-18 02:31:46 +09:00
r = " " ;
for ( int i = 0 ; h_nodes [ i ] ! = NULL ; i + + ) {
for ( xl_node_t * child = h_nodes [ i ] - > first_child ; child ! = NULL ; child = child - > next ) {
if ( child - > type ! = XL_NODE_NODE ) continue ;
r + = scan_widget_handler_header ( child , name , " \t \t " , 0 ) ;
}
}
2026-04-17 19:42:14 +09:00
if ( r ! = " " ) OFS < < std : : endl
< < r ;
}
2026-04-20 05:29:42 +09:00
if ( f_nodes ! = NULL ) {
std : : string r ;
r = " " ;
for ( int i = 0 ; f_nodes [ i ] ! = NULL ; i + + ) {
for ( xl_node_t * child = f_nodes [ i ] - > first_child ; child ! = NULL ; child = child - > next ) {
if ( child - > type ! = XL_NODE_NODE ) continue ;
r + = widget_function_header ( child , " \t \t " ) ;
}
}
if ( r ! = " " ) OFS < < std : : endl
< < r ;
}
2026-04-17 19:42:14 +09:00
OFS < < " }; " < < std : : endl ;
OFS < < " }; // namespace MwCXX " < < std : : endl ;
OFS < < std : : endl ;
OFS < < " #endif " < < std : : endl ;
# undef OFS
2026-04-18 01:05:20 +09:00
# define OFS files["W" + name + ".cc"]
2026-04-17 19:42:14 +09:00
2026-04-18 01:05:20 +09:00
OFS = std : : ofstream ( " src/widget/ " + lowercase ( name ) + " .cc " ) ;
2026-04-17 19:42:14 +09:00
2026-09-27 07:23:30 +09:00
if ( name = = " OpenGL " | | name = = " Vulkan " | | name = = " Direct3D9 " ) OFS < < " #define MW_ " + uppercase ( name ) + " _NO_INCLUDE " < < std : : endl ;
2026-04-17 19:42:14 +09:00
OFS < < " #include <MwCXX/Widget/ " + name + " .h> " < < std : : endl ;
OFS < < std : : endl ;
2026-04-18 01:05:20 +09:00
OFS < < " MwCXX:: " + name + " :: " + name + " (MwWidget widget, MwCXX::Base* parent) : MwCXX::Base(widget, parent) { " < < std : : endl ;
2026-04-17 22:25:28 +09:00
OFS < < " this->RegisterHandlers(); " < < std : : endl ;
2026-04-17 19:42:14 +09:00
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 ;
2026-04-17 22:25:28 +09:00
OFS < < " this->RegisterHandlers(); " < < std : : endl ;
2026-04-17 19:42:14 +09:00
OFS < < " } " < < std : : endl ;
OFS < < std : : endl ;
2026-04-17 22:25:28 +09:00
if ( p_nodes ! = NULL ) {
2026-04-18 01:05:20 +09:00
for ( int i = 0 ; p_nodes [ i ] ! = NULL ; i + + ) {
2026-04-18 02:31:46 +09:00
for ( xl_node_t * child = p_nodes [ i ] - > first_child ; child ! = NULL ; child = child - > next ) {
2026-04-18 01:05:20 +09:00
if ( child - > type ! = XL_NODE_NODE ) continue ;
OFS < < scan_widget_property_source ( child , name ) ;
}
2026-04-17 22:25:28 +09:00
}
}
if ( h_nodes ! = NULL ) {
2026-04-18 01:05:20 +09:00
for ( int i = 0 ; h_nodes [ i ] ! = NULL ; i + + ) {
2026-04-18 02:31:46 +09:00
for ( xl_node_t * child = h_nodes [ i ] - > first_child ; child ! = NULL ; child = child - > next ) {
2026-04-18 01:05:20 +09:00
if ( child - > type ! = XL_NODE_NODE ) continue ;
OFS < < scan_widget_handler_source ( child , name ) ;
}
2026-04-17 22:25:28 +09:00
}
}
OFS < < " void MwCXX:: " + name + " ::RegisterHandlers() { " < < std : : endl ;
if ( h_nodes ! = NULL ) {
2026-04-18 02:31:46 +09:00
int f ;
f = 0 ;
2026-04-18 01:05:20 +09:00
for ( int i = 0 ; h_nodes [ i ] ! = NULL ; i + + ) {
for ( xl_node_t * child = h_nodes [ i ] - > first_child ; child ! = NULL ; child = child - > next ) {
2026-04-17 22:25:28 +09:00
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 ;
2026-04-18 02:31:46 +09:00
f = 1 ;
}
}
if ( f ) OFS < < std : : endl ;
for ( int i = 0 ; h_nodes [ i ] ! = NULL ; i + + ) {
for ( xl_node_t * 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 < < " this-> " + upperfirst ( hname ) + " Handler = NULL; " < < std : : endl ;
2026-04-17 22:25:28 +09:00
}
2026-04-17 19:42:14 +09:00
}
}
2026-04-17 22:25:28 +09:00
OFS < < " } " < < std : : endl ;
2026-04-20 05:29:42 +09:00
OFS < < std : : endl ;
if ( f_nodes ! = NULL ) {
for ( int i = 0 ; f_nodes [ i ] ! = NULL ; i + + ) {
for ( xl_node_t * child = f_nodes [ i ] - > first_child ; child ! = NULL ; child = child - > next ) {
if ( child - > type ! = XL_NODE_NODE ) continue ;
OFS < < widget_function_source ( child , name ) ;
}
}
}
2026-04-17 19:42:14 +09:00
# undef OFS
2026-04-17 22:25:28 +09:00
if ( p_nodes ! = NULL ) free ( p_nodes ) ;
if ( h_nodes ! = NULL ) free ( h_nodes ) ;
2026-04-20 05:29:42 +09:00
if ( f_nodes ! = NULL ) free ( f_nodes ) ;
2026-04-17 19:42:14 +09:00
files [ " objs " ] < < " src/widget/ " + lowercase ( name ) + " .o " ;
}
2026-04-18 02:31:46 +09:00
static std : : string function_decl ( xl_node_t * node , std : : string prefix = " " ) {
xl_node_t * ret = NULL ;
2026-04-18 01:05:20 +09:00
xl_node_t * * nodes ;
std : : string r = " " ;
2026-04-17 19:42:14 +09:00
2026-04-18 02:31:46 +09:00
if ( ( nodes = xl_get_path ( node , " return " ) ) ! = NULL ) {
for ( int i = 0 ; nodes [ i ] ! = NULL ; i + + ) {
for ( xl_node_t * child = nodes [ i ] - > first_child ; child ! = NULL ; child = child - > next ) {
2026-04-18 01:05:20 +09:00
if ( child - > type = = XL_NODE_NODE ) ret = child ;
}
}
2026-04-18 02:31:46 +09:00
free ( nodes ) ;
2026-04-18 01:05:20 +09:00
}
2026-04-17 19:42:14 +09:00
2026-04-18 02:31:46 +09:00
if ( ret = = NULL ) {
2026-04-18 01:05:20 +09:00
r + = " void " ;
2026-04-18 02:31:46 +09:00
} else {
2026-04-18 01:05:20 +09:00
r + = get_ctype ( xml_to_type ( ret ) , 0 , 0 ) + " " ;
}
r + = prefix + std : : string ( xl_get_attribute ( node , " name " ) ) . substr ( 2 ) ;
r + = " ( " ;
2026-04-18 02:31:46 +09:00
if ( ( nodes = xl_get_path ( node , " arguments " ) ) ! = NULL ) {
for ( int i = 0 ; nodes [ i ] ! = NULL ; i + + ) {
for ( xl_node_t * child = nodes [ i ] - > first_child ; child ! = NULL ; child = child - > next ) {
2026-04-18 01:05:20 +09:00
if ( child - > type ! = XL_NODE_NODE ) continue ;
if ( r . substr ( r . size ( ) - 1 , 1 ) ! = " ( " ) r + = " , " ;
2026-04-18 02:31:46 +09:00
r + = get_ctype ( xml_to_type ( child ) , 1 , 0 ) ;
2026-04-18 01:05:20 +09:00
}
}
2026-04-18 02:31:46 +09:00
free ( nodes ) ;
2026-04-18 01:05:20 +09:00
}
r + = " ) " ;
return r ;
}
2026-04-18 02:31:46 +09:00
static std : : string function_source ( xl_node_t * node ) {
std : : stringstream strm ;
xl_node_t * * nodes ;
xl_node_t * ret = NULL ;
xl_node_t * widget = NULL ;
typeinfo type ;
int first = 1 ;
if ( ( nodes = xl_get_path ( node , " return " ) ) ! = NULL ) {
for ( int i = 0 ; nodes [ i ] ! = NULL ; i + + ) {
for ( xl_node_t * child = nodes [ i ] - > first_child ; child ! = NULL ; child = child - > next ) {
if ( child - > type = = XL_NODE_NODE ) ret = child ;
}
}
free ( nodes ) ;
}
strm < < function_decl ( node , " MwCXX:: " ) < < " { " < < std : : endl ;
strm < < " " ;
if ( ret ! = NULL ) {
type = xml_to_type ( ret ) ;
if ( type . type = = " widget " ) {
std : : string str = get_ctype ( type , 0 ) ;
strm < < " return new " + str . substr ( 0 , str . size ( ) - 1 ) + " ( " ;
} else {
strm < < " return ( " + get_ctype ( type , 0 ) + " ) " ;
}
}
strm < < std : : string ( xl_get_attribute ( node , " name " ) ) + " ( " ;
first = 1 ;
if ( ( nodes = xl_get_path ( node , " arguments " ) ) ! = NULL ) {
for ( int i = 0 ; nodes [ i ] ! = NULL ; i + + ) {
for ( xl_node_t * child = nodes [ i ] - > first_child ; child ! = NULL ; child = child - > next ) {
typeinfo type2 ;
if ( child - > type ! = XL_NODE_NODE ) continue ;
if ( std : : string ( child - > name ) = = " widget " & & widget = = NULL ) widget = child ;
type2 = xml_to_type ( child ) ;
if ( first ) {
first = 0 ;
} else {
strm < < " , " ;
}
if ( type2 . type = = " widget " ) {
2026-04-20 00:47:40 +09:00
strm < < " ( " + type2 . name + " == NULL ? NULL : " + type2 . name + " ->GetWidget()) " ;
2026-04-18 02:31:46 +09:00
} else {
if ( type2 . type = = " string " ) {
strm < < std : : endl ;
strm < < " #ifdef MWCXX_USE_C_STRING " < < std : : endl ;
strm < < type2 . name < < std : : endl ;
strm < < " #else " < < std : : endl ;
strm < < type2 . name + " .c_str() " < < std : : endl ;
strm < < " #endif " < < std : : endl ;
strm < < " " ;
} else {
strm < < " ( " + get_ctype ( type2 , 0 ) + " ) " + type2 . name ;
}
}
}
}
free ( nodes ) ;
}
if ( ret ! = NULL & & type . type = = " widget " ) {
strm < < " ) " ;
if ( widget ! = NULL ) strm < < " , " + std : : string ( xl_get_attribute ( widget , " name " ) ) ;
}
strm < < " ); " < < std : : endl ;
strm < < " } " < < std : : endl ;
return strm . str ( ) ;
2026-04-18 01:05:20 +09:00
}
2026-04-18 02:31:46 +09:00
static std : : string function_header ( xl_node_t * node ) {
2026-04-18 01:05:20 +09:00
return function_decl ( node ) + " ; " ;
}
static void scan_header ( xl_node_t * node ) {
std : : string name ;
if ( node - > type ! = XL_NODE_NODE ) return ;
name = xl_get_attribute ( node , " name " ) ;
2026-04-18 02:31:46 +09:00
if ( name . size ( ) > = 7 & & name . substr ( 0 , 7 ) = = " Dialog/ " ) {
2026-04-18 01:05:20 +09:00
xl_node_t * * nodes ;
# define OFS files["D" + name.substr(7) + ".h"]
OFS = std : : ofstream ( " include/MwCXX/ " + name + " .h " ) ;
OFS < < " #ifndef __MWCXX_DIALOG_ " + uppercase ( name . substr ( 7 ) ) + " _H__ " < < std : : endl ;
OFS < < " #define __MWCXX_DIALOG_ " + uppercase ( name . substr ( 7 ) ) + " _H__ " < < std : : endl ;
OFS < < std : : endl ;
2026-04-18 02:31:46 +09:00
OFS < < " #include <MwCXX/Widget/All.h> " < < std : : endl ;
OFS < < std : : endl ;
2026-04-18 01:05:20 +09:00
OFS < < " namespace MwCXX { " < < std : : endl ;
2026-04-18 02:31:46 +09:00
if ( ( nodes = xl_get_path ( node , " functions " ) ) ! = NULL ) {
for ( int i = 0 ; nodes [ i ] ! = NULL ; i + + ) {
for ( xl_node_t * child = nodes [ i ] - > first_child ; child ! = NULL ; child = child - > next ) {
2026-04-18 01:05:20 +09:00
if ( child - > type ! = XL_NODE_NODE ) continue ;
OFS < < " " + function_header ( child ) < < std : : endl ;
}
}
free ( nodes ) ;
}
OFS < < " }; // namespace MwCXX " < < std : : endl ;
OFS < < std : : endl ;
OFS < < " #endif " < < std : : endl ;
# undef OFS
# define OFS files["D" + name.substr(7) + ".cc"]
2026-04-18 02:31:46 +09:00
OFS = std : : ofstream ( " src/dialog/ " + lowercase ( name . substr ( 7 ) ) + " .cc " ) ;
OFS < < " #include <MwCXX/ " + name + " .h> " < < std : : endl ;
OFS < < std : : endl ;
if ( ( nodes = xl_get_path ( node , " functions " ) ) ! = NULL ) {
for ( int i = 0 ; nodes [ i ] ! = NULL ; i + + ) {
for ( xl_node_t * child = nodes [ i ] - > first_child ; child ! = NULL ; child = child - > next ) {
if ( child - > type ! = XL_NODE_NODE ) continue ;
OFS < < function_source ( child ) ;
}
}
free ( nodes ) ;
}
files [ " objs " ] < < " src/dialog/ " + lowercase ( name . substr ( 7 ) ) + " .o " ;
2026-04-18 01:05:20 +09:00
# undef OFS
2026-04-17 19:42:14 +09:00
}
}
static void base_widget ( ) {
2026-04-17 22:25:28 +09:00
int f ;
2026-04-17 19:42:14 +09:00
# define OFS files["WBaseAuto.h"]
OFS = std : : ofstream ( " include/MwCXX/Widget/BaseAuto.h " ) ;
2026-04-17 22:25:28 +09:00
f = 0 ;
2026-04-17 19:42:14 +09:00
for ( auto p = props . begin ( ) ; p ! = props . end ( ) ; p + + ) {
if ( ! p - > second . common ) continue ;
OFS < < widget_property_header ( p - > first ) ;
2026-04-17 22:25:28 +09:00
f = 1 ;
}
2026-04-18 02:31:46 +09:00
if ( f ) OFS < < std : : endl ;
2026-04-17 22:25:28 +09:00
2026-04-18 02:31:46 +09:00
f = 0 ;
for ( auto p = handlers . begin ( ) ; p ! = handlers . end ( ) ; p + + ) {
if ( ! p - > second . common ) continue ;
OFS < < widget_handler_header ( " Base " , p - > first ) ;
f = 1 ;
}
2026-04-17 22:25:28 +09:00
if ( f ) OFS < < std : : endl ;
for ( auto p = handlers . begin ( ) ; p ! = handlers . end ( ) ; p + + ) {
if ( ! p - > second . common ) continue ;
2026-04-18 02:31:46 +09:00
OFS < < widget_handler_header ( " Base " , p - > first , " " , 0 ) ;
2026-04-17 19:42:14 +09:00
}
# undef OFS
2026-04-18 01:05:20 +09:00
# define OFS files["WBaseAuto.cc"]
2026-04-17 19:42:14 +09:00
2026-04-18 01:05:20 +09:00
OFS = std : : ofstream ( " src/widget/baseauto.cc " ) ;
2026-04-17 19:42:14 +09:00
OFS < < " #include <MwCXX/Widget/Base.h> " < < std : : endl ;
for ( auto p = props . begin ( ) ; p ! = props . end ( ) ; p + + ) {
if ( ! p - > second . common ) continue ;
2026-04-17 22:25:28 +09:00
OFS < < widget_property_source ( " Base " , p - > first ) ;
}
for ( auto h = handlers . begin ( ) ; h ! = handlers . end ( ) ; h + + ) {
if ( ! h - > second . common ) continue ;
OFS < < widget_handler_source ( " Base " , h - > first ) ;
2026-04-17 19:42:14 +09:00
}
2026-04-17 22:25:28 +09:00
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 ;
}
2026-04-18 02:31:46 +09:00
OFS < < std : : endl ;
for ( auto h = handlers . begin ( ) ; h ! = handlers . end ( ) ; h + + ) {
if ( ! h - > second . common ) continue ;
OFS < < " this-> " + upperfirst ( h - > first ) + " Handler = NULL; " < < std : : endl ;
}
2026-04-17 22:25:28 +09:00
OFS < < " } " < < std : : endl ;
2026-04-17 19:42:14 +09:00
# undef OFS
files [ " objs " ] < < " src/widget/baseauto.o " ;
}
int main ( int argc , char * * argv ) {
2026-04-16 15:01:47 +09:00
xemil_t * h ;
2026-04-17 19:42:14 +09:00
int fail = 0 ;
2026-04-16 15:01:47 +09:00
2026-04-17 19:42:14 +09:00
if ( argc < 2 ) {
2026-04-17 22:44:19 +09:00
std : : cerr < < " Usage: " + std : : string ( argv [ 0 ] ) + " XML " < < std : : endl ;
2026-04-16 15:01:47 +09:00
return 1 ;
}
2026-04-17 19:42:14 +09:00
locale = std : : locale : : classic ( ) ;
2026-04-16 15:01:47 +09:00
h = xl_open_file ( argv [ 1 ] ) ;
2026-04-17 19:42:14 +09:00
if ( h ! = NULL ) {
2026-04-16 15:01:47 +09:00
h - > param . new_text = 1 ;
if ( xl_parse ( h ) ) {
xl_node_t * * nodes ;
2026-04-17 19:42:14 +09:00
files [ " objs " ] = std : : ofstream ( " objs.mk " ) ;
2026-04-16 15:01:47 +09:00
2026-04-17 19:42:14 +09:00
files [ " objs " ] < < " OBJS += " ;
2026-04-16 15:01:47 +09:00
2026-04-17 19:42:14 +09:00
if ( ( nodes = xl_get_path ( h - > root , " properties " ) ) ! = NULL ) {
for ( int i = 0 ; nodes [ i ] ! = NULL ; i + + ) {
2026-04-18 02:31:46 +09:00
for ( xl_node_t * child = nodes [ i ] - > first_child ; child ! = NULL ; child = child - > next ) {
2026-04-18 01:05:20 +09:00
if ( child - > type ! = XL_NODE_NODE ) continue ;
scan_property ( child ) ;
}
2026-04-16 15:01:47 +09:00
}
2026-04-17 19:42:14 +09:00
free ( nodes ) ;
}
2026-04-17 22:25:28 +09:00
if ( ( nodes = xl_get_path ( h - > root , " handlers " ) ) ! = NULL ) {
for ( int i = 0 ; nodes [ i ] ! = NULL ; i + + ) {
2026-04-18 02:31:46 +09:00
for ( xl_node_t * child = nodes [ i ] - > first_child ; child ! = NULL ; child = child - > next ) {
2026-04-18 01:05:20 +09:00
if ( child - > type ! = XL_NODE_NODE ) continue ;
scan_handler ( child ) ;
}
}
free ( nodes ) ;
}
if ( ( nodes = xl_get_path ( h - > root , " headers " ) ) ! = NULL ) {
for ( int i = 0 ; nodes [ i ] ! = NULL ; i + + ) {
2026-04-18 02:31:46 +09:00
for ( xl_node_t * child = nodes [ i ] - > first_child ; child ! = NULL ; child = child - > next ) {
2026-04-18 01:05:20 +09:00
if ( child - > type ! = XL_NODE_NODE ) continue ;
scan_header ( child ) ;
}
2026-04-17 22:25:28 +09:00
}
free ( nodes ) ;
}
2026-04-17 19:42:14 +09:00
base_widget ( ) ;
2026-04-18 02:31:46 +09:00
# define OFS files["AllWidgets.h"]
OFS = std : : ofstream ( " include/MwCXX/Widget/All.h " ) ;
OFS < < " #ifndef __MWCXX_WIDGET_ALL_H__ " < < std : : endl ;
OFS < < " #define __MWCXX_WIDGET_ALL_H__ " < < std : : endl ;
OFS < < std : : endl ;
2026-04-17 19:42:14 +09:00
if ( ( nodes = xl_get_path ( h - > root , " widgets " ) ) ! = NULL ) {
for ( int i = 0 ; nodes [ i ] ! = NULL ; i + + ) {
2026-04-18 02:31:46 +09:00
for ( xl_node_t * child = nodes [ i ] - > first_child ; child ! = NULL ; child = child - > next ) {
std : : string name ;
if ( child - > type ! = XL_NODE_NODE ) continue ;
2026-04-18 01:05:20 +09:00
scan_widget ( child ) ;
2026-04-18 02:31:46 +09:00
name = xl_get_attribute ( child , " name " ) ;
2026-09-27 07:21:54 +09:00
if ( name = = " OpenGL " | | name = = " Vulkan " | | name = = " Direct3D9 " ) continue ;
2026-04-18 02:31:46 +09:00
OFS < < " #include <MwCXX/Widget/ " + name + " .h> " < < std : : endl ;
2026-04-18 01:05:20 +09:00
}
2026-04-17 19:42:14 +09:00
}
free ( nodes ) ;
2026-04-16 15:01:47 +09:00
}
2026-04-18 02:31:46 +09:00
OFS < < std : : endl ;
OFS < < " #endif " < < std : : endl ;
# undef OFS
2026-04-17 19:42:14 +09:00
files [ " objs " ] < < std : : endl ;
2026-04-16 15:01:47 +09:00
2026-04-17 19:42:14 +09:00
for ( auto f = files . begin ( ) ; f ! = files . end ( ) ; f + + ) {
f - > second . close ( ) ;
}
} else {
2026-04-16 15:01:47 +09:00
fail = 1 ;
}
xl_close ( h ) ;
2026-04-17 19:42:14 +09:00
} else {
2026-04-16 15:01:47 +09:00
fail = 1 ;
}
2026-04-17 19:42:14 +09:00
if ( fail ) {
2026-04-17 22:44:19 +09:00
std : : cerr < < " Failed to parse XML " < < std : : endl ;
2026-04-16 15:01:47 +09:00
return 1 ;
}
return 0 ;
}