Re: Noob needs help with examples/foreachq

Eric Blake <[email protected]>
Newsgroups gmane.comp.gnu.m4.general
Organization Red Hat
Message-ID <[email protected]>
On 08/24/2011 08:54 AM, Jeff Barnes wrote:
> Need help with foreachq. My M4PATH includes the foreachq.m4 file.
>
> $ cat init_trans_from_states
>
> include(`foreachq.m4')

Why foreachq.m4, when the M4 manual documents it as being 
less-than-stellar?  Try foreachq2.m4 (or even 3 or 4) (they provide the 
same public interface, so each file should be a drop-in replacement, 
except that they fix the bugs inherent in foreachq.m4 with poor 
scalability and bad handling of defn(`iterator').

>
> So far so good. Now I want to put a comma between them, so I redefine the from_states rule to be:
>
>
> define(from_states, `foreachq(`y', `$@', y`, ')')

Your problem is insufficient quoting.  You should _always_ quote the 
first argument to define() so that you don't end up defining the 
expansion of the earlier definition of a macro that you intended to 
redefine.  Likewise, you generally want to follow the rule of thumb of 
one level of quotes per macro invocation, except where you are 
specifically trying to protect an active m4 character from 
interpretation by m4 (such as comma), where you use double quotes.

I haven't tested this, but think you'll be a lot better off with:

statemachine(`mystatemachine',
   `events(
   )',
   `states(
     `state(`State1', `State1', `composite', `State1_START',
       `deep_h_transitions(
         `deep_h_transition(`State1')'
       )'
     )',
     `state(`State4', `State1_State4', `normal', `0',
       `deep_h_transitions(
         `deep_h_transition(`State1')
         deep_h_transition(`State4')'
       )'
     )'
   )',
   `transitions(
     `transition(
       `State4_Playing1',
       `from_states(
         `from_state(`State4')',
         `from_state(`State1')'
       )',
       `to_states(
         `to_state(`State2')',
         `to_state(`Playing1')'
       )',
       `transitionEvent(`my_event')',
       `transitionAction(`myaction')',
       `dest(`NORMAL_DEST')'
     )'
   )'
)



include(`foreachq.m4')
define(`statemachine',`

#include "statemachine.h"
#include "$1.h"

void
init_trans_from_states(void) {
$2 $3 $4
}
')
define(`events',`')
define(`event',`')
define(`states', `')
define(`transitions',`foreachq(`x', `$@', `x')')
define(`transition',`
   $1->fromStates = { `$2' };')
define(`from_states', `foreachq(`y', `$@', `y ')')
define(`from_state', `$1')
include(`mystatemachine.m4')



At which point, adding in your double-quoted comma would look like:

define(`from_states', `foreachq(`y', `$@', `y`, '')')

> Hmmm, what happened to State1? I know I'll need to do a counter or something to eventually not add an extra comma, but now it seems the $@ isn't right.

Your problem is that because you were underquoting arguments, m4 started 
treating the comma as an argument separator, rather than as a literal 
string, so you ended up calling statemachine() with (way) more than the 
intended 4 arguments.

-- 
Eric Blake   [email protected]    +1-801-349-2682
Libvirt virtualization library http://libvirt.org
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.