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

Re: Very complicated m4 stuff



On Fri, 2 Jul 1999, Xose Manoel Ramos wrote:

> El Mon, Jun 28, 1999 at 12:53:42AM +0200, Denis Barbier contaba:
> 
> >PS: I did not understand your other post, could you send a simple
> >    example to explain what you want?

A complete example, great ;-)

> I have such a group of m4 macros:
> 
> This defines a loop executes `_comando' for each element in a list. 
>  
> m4_define(<`_gira'>,<`m4_ifelse($#,1,<`_comando(<`$1'>)'>,<`_comando(<`$1'>)'><`
> _gira(m4_shift($@))'>)'>)
> 
> And this is very messy (as I supose m4 is most of the time). I have
> to redefine some commands, so the included file has some of this
> commands they will not be used (this could make some strange things). 
> 
> m4_define(<`_comando'>,<`
> m4_divert(-1)
> m4_pushdef(<`m4_divert'>)
> m4_pushdef(<`m4_sinclude'>)
> m4_include(<`macros.m4'>)
> m4_include(<`$1'>)
> m4_popdef(<`m4_sinclude'>)
> m4_popdef(<`m4_divert'>)
> m4_divert(0)m4_dnl
> _test_macro()
> m4_divert(0)m4_dnl
> '>)
> 
> Well, this probably is not easy understandable. Just an example:
> 
> I have several files this way:
> 
> ---- file3
> m4_define(_test_macro,xxxx)
> ----
> 
> ---- file2
> m4_define(_test_macro,yuyy)
> ----
> 
> ---- file1
> m4_define(_test_macro,zzzz)
> ----
> 
> And a file that calls the defined macros this way:
> 
> ------------ 
> _gira(file1,file2,file3)
> ------------
> 
> It will output:
> 
>  zzzz
>  yyyy
>  xxxx
> 
> Did somebody understand all this?

Hmmm, i hope so. What did you expect? This output seems good, isn't it?
  _gira(file1,file2,file3
expands to
  _comando(file1)_comando(file2)_comando(file3)
and then to
  zzzz
  yyyy
  xxxx

> Another way of explaining it. This code tries to include several
> files from a list inside the page. The program can extract certain
> information from them, and even do clever things: knowing what his
> name is, do not include itself. 
> 
> It this could be possible something like:
> 
> #include for(file*) do
>             if file == $(FILENAME) skip
>             else include it

Not directly via pass 1, ePerl is your friend.

> I don't know if I explain myself.
> 
> Well, I do this trick inside m4, but the problem is this is pass 4,
> so I cannot use Meta-HTML or eperl.

And so the solution is to rewrite it with Meta-HTML or eperl. Here are
some hints.
You can perform a kind of conditional inclusion via pass 1 like this:
$(INCLUDE_FILENAME:*# )#include 'file1'

File1 will be included only if INCLUDE_FILENAME is defined.
Of course, this is quite rough and you are certainly not very happy with
this.

Next try with Meta-HTML (not tested):

#use wml::std::tags
<define-tag alt-include>
<preserve src>
<set-var %attributes>
<ifeq <get-var src> "$(FILENAME)" ""
   <include <get-var src>>>
<restore src>
</define-tag>

<set-var list-of-files="file1\nfile2\nfile3">
<foreach file list-of-files>
  <alt-include src=<get-var file>>
</foreach>

But for such complex programming tasks, you should use ePerl.
#use wml::std::tags
<define-tag alt-include>
<preserve src>
<set-var %attributes>
<:
  my $file = qq(<get-var src>);
  if ($file ne '$(FILENAME)') {#  $(FILENAME) is expanded in pass1
    open(IN, "$file") || die;
    local($/) = undef;
    my $body = <IN>;
    close(IN);
    ... operations on $body ...
  }
:>
<restore src>
</define-tag>

Hope this helps.

--
Denis Barbier
WML Maintainer

______________________________________________________________________
Website META Language (WML)                www.engelschall.com/sw/wml/
Official Support Mailing List                   sw-wml@engelschall.com
Automated List Manager                       majordomo@engelschall.com