From: Mike A. <mik...@au...> - 2007-01-05 17:09:48
|
Hi - i've managed to do some *really* nice things with this software - but one thing keeps me back. Is there anyway to pass data around within the actions ? Background I'm trying to marshall (serialize) some C structures into XML. I've got a program which parses a definition of a C structure (if you've ever used RPCGEN or ONCRPC - it works on the same principle (and uses the .x file syntax :-)) and generates some code which dumps the XML. I'm now trying to get my parser to generate the .dtd and .act files for reading that file back in... Take this snippet of XML : <binding_comp_list> <binding_comp_list__abind VALUE="0"/> <binding_comp_list__type VALUE="70"/> <binding_comp_list__data SET='TRUE' VALUE=""/> </binding_comp_list> Ideally - I'd want to 1) allocate some memory for the binding_comp_list structure in the 'start' for 'binding_comp_list' 2) use that parent to set the data.. 3) use that memory in the 'end' 'binding_comp_list' to set something else.. ATM - i've done it using a series of temporary variables - but its really messy (because these things can recurse - so I can't just declare once temporary binding_comp_list - I need to use a dynamic array..) It gets even worse when the structure contains structure or an array ( or an array of structures!) For reference - that binding_comp_list is defined as : struct binding_comp_list { long abind; int type; string data; // basically a char* }; My current actions look like this (excuse any errors - i've modified this from the original for readability!): <start tag='something_using_a_binding_comp_list'> <![CDATA[ Allocate("binding_comp_list", (void *)&tmp_binding_comp_list, &tmp_binding_comp_list_cnt, sizeof(struct binding_comp_list)); ]]> </start> <end tag='something_using_a_binding_comp_list'> <![CDATA[ setsomething=tmp_binding_comp_list[tmp_binding_comp_list_cnt-1]; FreeMemory("binding_comp_list",(void ***)&tmp_binding_comp_list, &tmp_binding_comp_list_cnt,1); ]]> </end> <end tag='binding_comp_list__abind'> <![CDATA[ tmp_binding_comp_list[tmp_binding_comp_list_cnt-1]->abind=atol({VALUE}); ]]> </end> <end tag='binding_comp_list__type'> <![CDATA[ tmp_binding_comp_list[tmp_binding_comp_list_cnt-1]->type=atol({VALUE}); ]]> </end> <end tag='binding_comp_list__data'> <![CDATA[ if (isyes({SET})) { tmp_binding_comp_list[tmp_binding_comp_list_cnt-1]->data=strdup({VALUE}); } else { tmp_binding_comp_list[tmp_binding_comp_list_cnt-1]->data=0; } ]]> </end> Any thoughts ? (Or alternative ways of marshalling the C to XML and back ?!) -- Mike Aubury |
From: William F. D. <wil...@th...> - 2007-01-05 21:30:33
|
Hi Mike, This must be a common app for flexml -- it's one of my own main uses for it. I too need to do marshalling and the reverse for basic values, and recursive types built from them by vectoring and map (hash-table) formation, down to any depth. (E.g. lists of lists of maps of strings, etc.) My implementation language is C++, which (IMO) makes things a little cleaner than straight C since I don't need to use void*, or casting operations anyplace. It is a fundamental limitation of flex that the communication between actions can only take place by global variables. There is no way around that. But you can structure your code so that it is quite clean by using stack operations. This strategy will work for any basic data types and any collection of type constructors (e.g. vector-formation, struct-formation, binding_comp_list-formation, etc.) One global Stack object is all you need. When a start tag is seen in the XML, push onto the stack a placeholder object. When an end tag is seen, you'll know how many objects to pop (and what types they should be); pop them and build your object, putting it into the placeholder you had pushed. For type constructors (like vector<> in C++) that take a variable number of parameters, use the 'cons' strategy from LISP; that is, cons in each argument as you encounter it, as if you were building a right-branching binary tree. You definitely don't want to be allocating and freeing in every action -- let your stack operation (push/pop) definitions do that for you. I can send you some sample C++ code that implements these ideas if that would be useful. Will On Fri, 2007-01-05 at 17:10 +0000, Mike Aubury wrote: > Hi - i've managed to do some *really* nice things with this software - but one > thing keeps me back. > Is there anyway to pass data around within the actions ? > > > Background > > I'm trying to marshall (serialize) some C structures into XML. > I've got a program which parses a definition of a C structure (if you've ever > used RPCGEN or ONCRPC - it works on the same principle (and uses the .x file > syntax :-)) and generates some code which dumps the XML. > > I'm now trying to get my parser to generate the .dtd and .act files for > reading that file back in... > > Take this snippet of XML : > > <binding_comp_list> > <binding_comp_list__abind VALUE="0"/> > <binding_comp_list__type VALUE="70"/> > <binding_comp_list__data SET='TRUE' VALUE=""/> > </binding_comp_list> > > Ideally - I'd want to > 1) allocate some memory for the binding_comp_list structure > in the 'start' for 'binding_comp_list' > 2) use that parent to set the data.. > 3) use that memory in the 'end' 'binding_comp_list' to set something else.. > > ATM - i've done it using a series of temporary variables - but its really > messy (because these things can recurse - so I can't just declare once > temporary binding_comp_list - I need to use a dynamic array..) > It gets even worse when the structure contains structure or an array ( or an > array of structures!) > > > > For reference - that binding_comp_list is defined as : > > struct binding_comp_list { > long abind; > int type; > string data; // basically a char* > }; > > > > My current actions look like this (excuse any errors - i've modified this from > the original for readability!): > > <start tag='something_using_a_binding_comp_list'> > <![CDATA[ > Allocate("binding_comp_list", (void *)&tmp_binding_comp_list, > &tmp_binding_comp_list_cnt, sizeof(struct binding_comp_list)); > ]]> > </start> > > > > <end tag='something_using_a_binding_comp_list'> > <![CDATA[ > > setsomething=tmp_binding_comp_list[tmp_binding_comp_list_cnt-1]; > > FreeMemory("binding_comp_list",(void ***)&tmp_binding_comp_list, > &tmp_binding_comp_list_cnt,1); > > ]]> > </end> > > > > <end tag='binding_comp_list__abind'> > <![CDATA[ > tmp_binding_comp_list[tmp_binding_comp_list_cnt-1]->abind=atol({VALUE}); > > ]]> > </end> > > > <end tag='binding_comp_list__type'> > <![CDATA[ > tmp_binding_comp_list[tmp_binding_comp_list_cnt-1]->type=atol({VALUE}); > ]]> > </end> > > <end tag='binding_comp_list__data'> > <![CDATA[ > if (isyes({SET})) { > tmp_binding_comp_list[tmp_binding_comp_list_cnt-1]->data=strdup({VALUE}); > } else { > tmp_binding_comp_list[tmp_binding_comp_list_cnt-1]->data=0; > } > > ]]> > </end> > > Any thoughts ? > > > (Or alternative ways of marshalling the C to XML and back ?!) > -- William F Dowling wil...@th... www.scientific.thomson.com |
From: Mike A. <mik...@au...> - 2007-01-08 08:53:49
|
Follow up to this - am i right in assuming that we should not be accessing the attributes in an 'end' block ? If so - should doing this cause an error ? (My code wasn't working until I moved some of the checking to the 'start' block instead..) On Friday 05 January 2007 21:30, William F. Dowling wrote: > Hi Mike, > > This must be a common app for flexml -- it's one of my own main uses for > it. I too need to do marshalling and the reverse for basic values, and > recursive types built from them by vectoring and map (hash-table) > formation, down to any depth. (E.g. lists of lists of maps of strings, > etc.) My implementation language is C++, which (IMO) makes things a > little cleaner than straight C since I don't need to use void*, or > casting operations anyplace. > > It is a fundamental limitation of flex that the communication between > actions can only take place by global variables. There is no way around > that. > > But you can structure your code so that it is quite clean by using stack > operations. This strategy will work for any basic data types and any > collection of type constructors (e.g. vector-formation, > struct-formation, binding_comp_list-formation, etc.) One global Stack > object is all you need. > > When a start tag is seen in the XML, push onto the stack a placeholder > object. When an end tag is seen, you'll know how many objects to pop > (and what types they should be); pop them and build your object, putting > it into the placeholder you had pushed. For type constructors (like > vector<> in C++) that take a variable number of parameters, use the > 'cons' strategy from LISP; that is, cons in each argument as you > encounter it, as if you were building a right-branching binary tree. > > You definitely don't want to be allocating and freeing in every action > -- let your stack operation (push/pop) definitions do that for you. > > I can send you some sample C++ code that implements these ideas if that > would be useful. > > Will > > On Fri, 2007-01-05 at 17:10 +0000, Mike Aubury wrote: > > Hi - i've managed to do some *really* nice things with this software - > > but one thing keeps me back. > > Is there anyway to pass data around within the actions ? > > > > > > Background > > > > I'm trying to marshall (serialize) some C structures into XML. > > I've got a program which parses a definition of a C structure (if you've > > ever used RPCGEN or ONCRPC - it works on the same principle (and uses the > > .x file syntax :-)) and generates some code which dumps the XML. > > > > I'm now trying to get my parser to generate the .dtd and .act files for > > reading that file back in... > > > > Take this snippet of XML : > > > > <binding_comp_list> > > <binding_comp_list__abind VALUE="0"/> > > <binding_comp_list__type VALUE="70"/> > > <binding_comp_list__data SET='TRUE' VALUE=""/> > > </binding_comp_list> > > > > Ideally - I'd want to > > 1) allocate some memory for the binding_comp_list structure > > in the 'start' for 'binding_comp_list' > > 2) use that parent to set the data.. > > 3) use that memory in the 'end' 'binding_comp_list' to set something > > else.. > > > > ATM - i've done it using a series of temporary variables - but its really > > messy (because these things can recurse - so I can't just declare once > > temporary binding_comp_list - I need to use a dynamic array..) > > It gets even worse when the structure contains structure or an array ( or > > an array of structures!) > > > > > > > > For reference - that binding_comp_list is defined as : > > > > struct binding_comp_list { > > long abind; > > int type; > > string data; // basically a char* > > }; > > > > > > > > My current actions look like this (excuse any errors - i've modified this > > from the original for readability!): > > > > <start tag='something_using_a_binding_comp_list'> > > <![CDATA[ > > Allocate("binding_comp_list", (void *)&tmp_binding_comp_list, > > &tmp_binding_comp_list_cnt, sizeof(struct binding_comp_list)); > > ]]> > > </start> > > > > > > > > <end tag='something_using_a_binding_comp_list'> > > <![CDATA[ > > > > setsomething=tmp_binding_comp_list[tmp_binding_comp_list_cnt-1]; > > > > FreeMemory("binding_comp_list",(void ***)&tmp_binding_comp_list, > > &tmp_binding_comp_list_cnt,1); > > > > ]]> > > </end> > > > > > > > > <end tag='binding_comp_list__abind'> > > <![CDATA[ > > tmp_binding_comp_list[tmp_binding_comp_list_cnt-1]->abind=atol({VALUE}) > >; > > > > ]]> > > </end> > > > > > > <end tag='binding_comp_list__type'> > > <![CDATA[ > > tmp_binding_comp_list[tmp_binding_comp_list_cnt-1]->type=atol({VALUE}); > > ]]> > > </end> > > > > <end tag='binding_comp_list__data'> > > <![CDATA[ > > if (isyes({SET})) { > > > > tmp_binding_comp_list[tmp_binding_comp_list_cnt-1]->data=strdup({VALUE}); > > } else { > > > > tmp_binding_comp_list[tmp_binding_comp_list_cnt-1]->data=0; } > > > > ]]> > > </end> > > > > Any thoughts ? > > > > > > (Or alternative ways of marshalling the C to XML and back ?!) -- Mike Aubury |
From: William F. D. <wil...@th...> - 2007-01-08 15:12:59
|
On Mon, 2007-01-08 at 08:54 +0000, Mike Aubury wrote: > Follow up to this - am i right in assuming that we should not be accessing the > attributes in an 'end' block ? > If so - should doing this cause an error ? > > > (My code wasn't working until I moved some of the checking to the 'start' > block instead..) There was some discussion about this on on the flexml-users mailing list a few months ago: http://sourceforge.net/mailarchive/forum.php?thread_id=30370096&forum_id=593 I forget what the upshot was -- it looks like I investigated and at least thought the change (to make attributes accessible from the end-tag processing code) would be easy. Martin Quinson had asked for that. Martin: as far as you know, was that change made? Will -- William F Dowling wil...@th... www.scientific.thomson.com |
From: Mike A. <mik...@au...> - 2007-01-08 15:19:27
|
What version did this go in ? flexml --version reports I'm using FleXML version Id: flexml.pl,v 1.61 2006/09/13 16:34:33 wdowling Exp On Monday 08 January 2007 15:12, William F. Dowling wrote: > On Mon, 2007-01-08 at 08:54 +0000, Mike Aubury wrote: > > Follow up to this - am i right in assuming that we should not be > > accessing the attributes in an 'end' block ? > > If so - should doing this cause an error ? > > > > > > (My code wasn't working until I moved some of the checking to the 'start' > > block instead..) > > There was some discussion about this on on the flexml-users mailing list > a few months ago: > > http://sourceforge.net/mailarchive/forum.php?thread_id=30370096&forum_id=59 >3 > > I forget what the upshot was -- it looks like I investigated and at > least thought the change (to make attributes accessible from the end-tag > processing code) would be easy. Martin Quinson had asked for that. > > Martin: as far as you know, was that change made? > > Will -- Mike Aubury |
From: William F. D. <wil...@th...> - 2007-01-08 15:57:17
|
On Mon, 2007-01-08 at 15:20 +0000, Mike Aubury wrote: > What version did this go in ? > > flexml --version reports I'm using > FleXML version Id: flexml.pl,v 1.61 2006/09/13 16:34:33 wdowling Exp As of flexml.pl 1.58 you are supposed to have access to attributes from inside the end-tag processing code. Please enter a bug in the sourceforge bug tracker for flexml if you can confirm that attribute access inside end-tag processing is not working. Ideally, could you submit an absolutely minimal example that shows the failure? Thanks, Will > > On Monday 08 January 2007 15:12, William F. Dowling wrote: > > On Mon, 2007-01-08 at 08:54 +0000, Mike Aubury wrote: > > > Follow up to this - am i right in assuming that we should not be > > > accessing the attributes in an 'end' block ? > > > If so - should doing this cause an error ? > > > > > > > > > (My code wasn't working until I moved some of the checking to the 'start' > > > block instead..) > > > > There was some discussion about this on on the flexml-users mailing list > > a few months ago: > > > > http://sourceforge.net/mailarchive/forum.php?thread_id=30370096&forum_id=59 > >3 > > > > I forget what the upshot was -- it looks like I investigated and at > > least thought the change (to make attributes accessible from the end-tag > > processing code) would be easy. Martin Quinson had asked for that. > > > > Martin: as far as you know, was that change made? > > > > Will > -- William F Dowling wil...@th... www.scientific.thomson.com |
From: Mike A. <mik...@au...> - 2007-03-20 16:13:07
|
Long time - i know - but I've tracked the bug down to a minimal example (I hope !), its down to 'recursive' tags : <expr_str e_expr_type='ET_EXPR_FCALL' nm='fcall' > <s_expr_function_call> <expr_str nm='list' /> </s_expr_function_call> </expr_str> In this example - when we get to the second expr_str end tag - '{nm}' will be set to 'list' in the end tag - not 'fcall'... On Monday 08 January 2007 15:56, William F. Dowling wrote: > On Mon, 2007-01-08 at 15:20 +0000, Mike Aubury wrote: > > What version did this go in ? > > > > flexml --version reports I'm using > > FleXML version Id: flexml.pl,v 1.61 2006/09/13 16:34:33 wdowling Exp > > As of flexml.pl 1.58 you are supposed to have access to attributes from > inside the end-tag processing code. > > Please enter a bug in the sourceforge bug tracker for flexml if you can > confirm that attribute access inside end-tag processing is not working. > Ideally, could you submit an absolutely minimal example that shows the > failure? > > Thanks, > > Will > > > On Monday 08 January 2007 15:12, William F. Dowling wrote: > > > On Mon, 2007-01-08 at 08:54 +0000, Mike Aubury wrote: > > > > Follow up to this - am i right in assuming that we should not be > > > > accessing the attributes in an 'end' block ? > > > > If so - should doing this cause an error ? > > > > > > > > > > > > (My code wasn't working until I moved some of the checking to the > > > > 'start' block instead..) > > > > > > There was some discussion about this on on the flexml-users mailing > > > list a few months ago: > > > > > > http://sourceforge.net/mailarchive/forum.php?thread_id=30370096&forum_i > > >d=59 3 > > > > > > I forget what the upshot was -- it looks like I investigated and at > > > least thought the change (to make attributes accessible from the > > > end-tag processing code) would be easy. Martin Quinson had asked for > > > that. > > > > > > Martin: as far as you know, was that change made? > > > > > > Will -- Mike Aubury Aubit Computing Ltd is registered in England and Wales, Number: 3112827 Registered Address : Murlain Business Centre, Union Street, Chester, CH1 1QP |
From: William F. D. <wil...@th...> - 2007-03-20 16:28:18
|
Very interesting Mike. Thanks for the very clear example. I am almost positive that any code I had added to support attribute access from end-tags did *not* keep a stack of attribute values, thus accounting exactly for the behaviour you are seeing. So this is a definite bug. Until this bug gets fixed, I think you'll have to keep your own stack of attribute values that you are interested in, pushed at start-tag time and popped at end-tag time. That's not ideal, but at least your code could work that way. Thanks again for the bug report, Will On Tue, 2007-03-20 at 16:12 +0000, Mike Aubury wrote: > Long time - i know - but I've tracked the bug down to a minimal example (I > hope !), its down to 'recursive' tags : > > > > <expr_str e_expr_type='ET_EXPR_FCALL' nm='fcall' > > <s_expr_function_call> > <expr_str nm='list' /> > </s_expr_function_call> > </expr_str> > > > In this example - when we get to the second expr_str end tag - '{nm}' will be > set to 'list' in the end tag - not 'fcall'... > > > On Monday 08 January 2007 15:56, William F. Dowling wrote: > > On Mon, 2007-01-08 at 15:20 +0000, Mike Aubury wrote: > > > What version did this go in ? > > > > > > flexml --version reports I'm using > > > FleXML version Id: flexml.pl,v 1.61 2006/09/13 16:34:33 wdowling Exp > > > > As of flexml.pl 1.58 you are supposed to have access to attributes from > > inside the end-tag processing code. > > > > Please enter a bug in the sourceforge bug tracker for flexml if you can > > confirm that attribute access inside end-tag processing is not working. > > Ideally, could you submit an absolutely minimal example that shows the > > failure? > > > > Thanks, > > > > Will > > > > > On Monday 08 January 2007 15:12, William F. Dowling wrote: > > > > On Mon, 2007-01-08 at 08:54 +0000, Mike Aubury wrote: > > > > > Follow up to this - am i right in assuming that we should not be > > > > > accessing the attributes in an 'end' block ? > > > > > If so - should doing this cause an error ? > > > > > > > > > > > > > > > (My code wasn't working until I moved some of the checking to the > > > > > 'start' block instead..) > > > > > > > > There was some discussion about this on on the flexml-users mailing > > > > list a few months ago: > > > > > > > > http://sourceforge.net/mailarchive/forum.php?thread_id=30370096&forum_i > > > >d=59 3 > > > > > > > > I forget what the upshot was -- it looks like I investigated and at > > > > least thought the change (to make attributes accessible from the > > > > end-tag processing code) would be easy. Martin Quinson had asked for > > > > that. > > > > > > > > Martin: as far as you know, was that change made? > > > > > > > > Will > -- William F Dowling wil...@th... www.scientific.thomson.com |