m4-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Noob needs help with examples/foreachq


From: Eric Blake
Subject: Re: Noob needs help with examples/foreachq
Date: Wed, 24 Aug 2011 17:22:58 -0600
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.18) Gecko/20110621 Fedora/3.1.11-1.fc14 Lightning/1.0b3pre Mnenhy/0.8.3 Thunderbird/3.1.11

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   address@hidden    +1-801-349-2682
Libvirt virtualization library http://libvirt.org



reply via email to

[Prev in Thread] Current Thread [Next in Thread]