From: Mads L. <mad...@ya...> - 2009-04-11 13:18:03
|
Hi Kevin Ollivier wrote: > Hi Eric, > > On Apr 9, 2009, at 11:18 AM, Eric Kow wrote: > > > On Thu, Apr 09, 2009 at 18:57:29 +0100, Eric Kow wrote: > >> This is where Kevin Ollivier of wxWidgets pointed out something > >> interesting: in the current wxWidgets trunk, it should be possible to > >> automatically generate the C bindings from the Doxygen XML output. > >> In > >> fact, he has already done something similar for Python, metadata to > >> Python objects: > >> > >> http://trac.wxwidgets.org/browser/wxWidgets/trunk/docs/doxygen/doxymlparser.py > > > > Following up on this, I did > > > > svn checkout http://svn.wxwidgets.org/svn/wx/wxWidgets/trunk > > wxWidgets > > cd wxWidgets/doc/doxygen > > ./regen.sh > > python doxymlparser.py --report out/xml/classwx_button.xml > > > > Attached is the XML file (input) and the output of this script. > > > > Here is a small extract of the output: > > > > Class: wxButton > > Bases: wxControl > > Inlcudes: [] > > Brief Description: > > > > And... > > > > Method: SetLabel > > Return Type: void > > Params: [{u'type': u'const&', u'declname': u'label'}] > > Prototype: void wxButton::SetLabel(const wxString &label) > > Brief Description: > > > > What can we do with this? > > As a start, with a few lines of Python code after the > doxyparser.parse(file) calls in the script, you can do something like: > > # start code to autogenerate wxc.h > wxc_header = "" > > for aclass in doxyparse.classes: > for amethod in methods: > self_ref = "TSelf" > if amethod.name == "Create": > self_ref = "TClass" > wxc_header += "%s(%s) " % (self_ref, aclass.name) > else: > wxc_header += "%s " % (wxc_type_for_type(amethod.return_type) > > wxc_header += "%s_%s( %s _obj" % (aclass.name, amethod.name, > self_ref + (" + aclass.name + ")") > > for param in amethod.params: > wxc_header += ", %s %s" % (wxc_type_for_type(param["type"]), "_" + > param["declname"]) > # Note: uncomment this if you support adding default values > # if "defval" in param: > # wxc_header += "=" + param["defval"] > wxc_header += " );\n" > > wxc_file = open("wxc.h", "wb") > wxc_file.write(wxc_header) > wxc_file.close() > > # end code > > This is all just pseudo-code, and methods like wxc_type_for_type would > need implemented, and you'd also need to probably work out some > special logic for constructors, a list of classes to exclude, etc. but > this should give you an idea of how to start things off. Ideally you'd > actually have your own generate_c_bindings.py file that does an > "import doxyparser", then runs "doxyparse.parse()" itself rather than > extending the doxymlparser.py script, but anyway, just some ideas. I have made an initial attempt at a c_wrapper.py program. It is far from finished, but like the XSLT program, I did it to see if it was feasible. I have attached the program. My initial imprecision is that this could work out. Python is a very nice language, and it was a joy to make my little program. I am already further along than with the XSLT program, and I have spend a third of the time. And more importantly, it did not feel painful at all. I had to change doxymlparser.py a bit though, otherwise we get type-names like constwxString: > svn diff: Index: doxymlparser.py =================================================================== --- doxymlparser.py (revision 60099) +++ doxymlparser.py (working copy) @@ -98,7 +98,11 @@ if child.nodeType == child.ELEMENT_NODE and child.nodeName == "ref": text += getTextValue(child) if child.nodeType == child.TEXT_NODE: - text += child.nodeValue.strip() + #text += child.nodeValue.strip() + # We changed line above to remove qualifiers. Maybe we need another field on parameters? + for token in string.split(child.nodeValue.strip()): + if (token != "virtual" and token != "static" and token != "const"): + text += token return text Kevin, what do you think about this change? The output looks like: > python c_wrapper.py out/xml/classwx_button.xml | indent /* Constructor */ wxButton wxButton_wxButton (); /* Constructor */ wxButton wxButton_wxButton (wxWindow * _parent, wxWindowID _id, wxString & _label, wxPoint & _pos, wxSize & _size, long _style, wxValidator & _validator, wxString & _name); void wxButton_Destruct (wxButton * _obj); bool wxButton_Create (wxButton _obj, wxWindow * _parent, wxWindowID _id, wxString & _label, wxPoint & _pos, wxSize & _size, long _style, wxValidator & _validator, wxString & _name); wxString wxButton_GetLabel (wxButton _obj); wxWindow *wxButton_SetDefault (wxButton _obj); void wxButton_SetLabel (wxButton _obj, wxString & _label); wxSize wxButton_GetDefaultSize (wxButton _obj); Greetings, Mads Lindstrøm |