From: Eric K. <eri...@gm...> - 2009-04-09 17:57:41
|
Hi everybody, I've recently been thinking about ways we would make the wxhaskell installation process less painful. My desire is for the "cabal install" part of the process to be completely painless. Right now, the wxcore process is slow, complicated and doesn't work for the user package database (which means you can't just cabal install any old program that uses wxhaskell). What I hope we can do is to segregate all the slow and painful stuff into C land (using standard stuff like autotools), keeping the Haskell-y bits nice and smooth. I think this will reduce the net pain because then people can just think in terms of (1) installing all the backend stuff like wxWidgets and (2) cabal install. A second desire would be for us to get rid of our wxc code altogether and move it to its own project? WXC is shared by wxHaskell, wxOcaml and wxEiffel, but we all have our own variants of the code. There was a wxc project, but it seems to have gone dead. I've remarked on #wxwidgets that it would be great if the wxWidgets team to take over the WXC project so that it would be more actively maintained. 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 This makes me wonder: can we do something similar for wxHaskell or wxc? What if wxc was generated in the same fashion? Instead of having this be some whole other project, why not make it ridiculously easy for the wxWidgets team to just ship a C interface around wxWidgets? I'm vaguely aware that our copy of wxc has some information which helps us keep track of the wxWidgets class hierarchy. Presumably the same information could be autogenerated as well? This sort of thing has been suggested before (people have mentioned SWIG). Now that wxHaskell 0.11 has been released with wxWidgets 2.8 support, is it time to take this back-end stuff more seriously? It sounds like what one of us could do is hack up a quick XSLT sheet or something similar to produce the C bindings. Maybe a HaXml program as a prototype? What should we do next? Thanks! -- Eric Kow <http://www.nltg.brighton.ac.uk/home/Eric.Kow> PGP Key ID: 08AC04F9 |
From: Eric K. <eri...@gm...> - 2009-04-09 18:18:26
Attachments:
classwx_button.xml
wx-button.out
|
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? -- Eric Kow <http://www.nltg.brighton.ac.uk/home/Eric.Kow> PGP Key ID: 08AC04F9 |
From: Mads L. <mad...@ya...> - 2009-04-10 16:44:18
|
Hi 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. > I had a quick look at the output and it seems to have some shortcomings. The output has only one constructor, whereas the input XML has two. Many of the return types also seems missing. Eg. Method: GetLabel Return Type: Params: [] Prototype: wxString wxButton::GetLabel() const Brief Description: Regarding the return type, we could parse the prototype string and ignore the "Return type". Greetings, Mads Lindstrøm |
From: Kevin O. <ke...@th...> - 2009-04-09 19:14:28
|
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. Regards, Kevin > -- > Eric Kow <http://www.nltg.brighton.ac.uk/home/Eric.Kow> > PGP Key ID: 08AC04F9 > <classwx_button.xml><wx-button.out> |
From: Mads L. <mad...@ya...> - 2009-04-10 10:19:40
|
Hi Eric Kow wrote: > I'm vaguely aware that our copy of wxc has some information which helps > us keep track of the wxWidgets class hierarchy. Presumably the same > information could be autogenerated as well? This sort of thing has been > suggested before (people have mentioned SWIG). > It seems that the SWIG team is in the process of making a C++ -> C binding, see: http://www.nabble.com/C%2B%2B-to-C-td22947590.html It is still in development and I do not know if it is (will become) usable for us. Greetings, Mads Lindstrøm |
From: Mads L. <mad...@ya...> - 2009-04-10 23:57:47
Attachments:
cpp_to_c.xsl
out.cpp
|
Hi 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: .... > > Now that wxHaskell 0.11 has been released with wxWidgets 2.8 support, is > it time to take this back-end stuff more seriously? It sounds like what > one of us could do is hack up a quick XSLT sheet or something similar to > produce the C bindings. Maybe a HaXml program as a prototype? I have never done any XSLT programming before (have done some XPath though), but still thought I would give it a try. I have attached the XSL program and the output. The XSLT program is nowhere near finished, just a beginning to see if it is a path worth pursuing. And to get feedback... Besides the overly verbose syntax, I did not feel like XSLT were a good match for the task. It was hard to factor out common patterns - aka. the composability of XSLT seems poor. But this may just be my lack of experience with XSLT. If I could have done something smarter I am all ears. I used to Saxon 8.8J for processing. Greetings, Mads Lindstrøm |
From: Eric Y. K. <eri...@gm...> - 2009-04-11 00:01:55
|
On Sat, Apr 11, 2009 at 01:57:30 +0200, Mads Lindstrøm wrote: > Besides the overly verbose syntax, I did not feel like XSLT were a good > match for the task. I realise you weren't talking about the syntax, but in case it plays a role in this, there is always PXSL, which has significantly dampened my dislike of all things XML http://community.moertel.com/pxsl/ PXSL also has some XSLT shortcuts which are handy... > It was hard to factor out common patterns - aka. the > composability of XSLT seems poor. But this may just be my lack of > experience with XSLT. If I could have done something smarter I am all > ears. -- Eric Kow <http://www.nltg.brighton.ac.uk/home/Eric.Kow> PGP Key ID: 08AC04F9 |
From: Mads L. <mad...@ya...> - 2009-04-11 10:43:58
|
Hi Eric Y. Kow wrote: > On Sat, Apr 11, 2009 at 01:57:30 +0200, Mads Lindstrøm wrote: > > Besides the overly verbose syntax, I did not feel like XSLT were a good > > match for the task. > > I realise you weren't talking about the syntax, but in case it plays a > role in this, there is always PXSL, which has significantly dampened my > dislike of all things XML > http://community.moertel.com/pxsl/ > > PXSL also has some XSLT shortcuts which are handy... PSXL looks nice. Actually, syntax was part of the problem. Maybe my English was not too good in my post. After "everything" turning XML in Java-land, I used to joke about people making a programming language with XML syntax, which I thought to be obviously stupid. So lesson is: Be careful about what you joke about it, it might come true... Greetings, Mads Lindstrøm |
From: Mads L. <mad...@ya...> - 2009-04-11 13:18:03
Attachments:
c_wrapper.py
|
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 |
From: Mads L. <mad...@ya...> - 2009-04-12 17:23:13
|
Hi I made another version of the c_wrapper.py program. I have attached the program, a new smaller diff to doxymlparser.py and output from running the program. The output can compile now: > python c_wrapper.py out/xml/classwx_button.xm > g++ `wx-config --libs` `wx-config --cxxflags` -c wrapped_wxButton.cpp I have not tried hooking it up to Haskell, as I cannot compile wxHaskell with the svn-checkout of wxWidgets and as I could not find the doxygen-directory in my older version of wxWidgets (2.8.7) which do work with wxHaskell. Also I think we should consider how to proceed. Should we proceed with making a python program like c_wrapper.py ? And how much work is there in this? I guess we need to: * Finish the c_wrapper.py script. It will properly need a lot of debugging before working properly. * Re-hook wxHaskell up to the output of c_wrapper.py script. This may take some time, as function names and some parameters will change. And a lot of code will have small changes, so there is a lot of possibility for error :-( * Convince the wxWidgets team to maintain the script. I guess this involves not just talking to the wxWidges team, but also show that other people will find the c-wrapper useful. Especially the second task seems big, but the others are not small either. If people are interested in working on c_wrapper.py, I would be happy to put it into our Darcs repo. Greetings, Mads Lindstrøm Mads Lindstrøm wrote: > 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 > |
From: Eric Y. K. <eri...@gm...> - 2009-04-12 17:38:36
|
On Sun, Apr 12, 2009 at 19:23:01 +0200, Mads Lindstrøm wrote: > * Convince the wxWidgets team to maintain the script. I guess this > involves not just talking to the wxWidges team, but also show that other > people will find the c-wrapper useful. This would be a big win and I think we may be able to pull this off. After all, wxOCaml, wxEiffel, and wxHaskell all use some variant of wxc. wx.NET have this thing they call wx-c, which I guess is to C# what wxc is to C. Maybe we could somehow adapt this technique? I can foresee this sort of thing helping wxWidgets become useful for new languages as well, or maybe even people who want to use wxWidgets in C for whatever reason. -- Eric Kow <http://www.nltg.brighton.ac.uk/home/Eric.Kow> PGP Key ID: 08AC04F9 |
From: Kevin O. <ke...@th...> - 2009-04-13 01:06:16
|
Hi Eric, Mads, and all, On Apr 12, 2009, at 10:38 AM, Eric Y. Kow wrote: > On Sun, Apr 12, 2009 at 19:23:01 +0200, Mads Lindstrøm wrote: >> * Convince the wxWidgets team to maintain the script. I guess this >> involves not just talking to the wxWidges team, but also show that >> other >> people will find the c-wrapper useful. > > This would be a big win and I think we may be able to pull this off. > After all, wxOCaml, wxEiffel, and wxHaskell all use some variant of > wxc. wx.NET have this thing they call wx-c, which I guess is to > C# what wxc is to C. Maybe we could somehow adapt this technique? > I can foresee this sort of thing helping wxWidgets become useful for > new languages as well, or maybe even people who want to use wxWidgets > in C for whatever reason. What I'd recommend you guys do is get the other ports that use C wrappers in together and try to work out a standardized wxC syntax for all the ports to use. (e.g. I see wxHaskell seems to use some TClass, etc. types but I'm not sure what they're for.) I don't think the wx developers will have any problem with hosting the script as part of the official wx tree, but we'd need people who are familiar with the needs of the C bindings to come up with the design of it and help out on maintaining the scripts. Regards, Kevin > -- > Eric Kow <http://www.nltg.brighton.ac.uk/home/Eric.Kow> > PGP Key ID: 08AC04F9 |