m4-discuss
[Top][All Lists]
Advanced

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

Re: General outline of what I'm trying to do


From: Eric Blake
Subject: Re: General outline of what I'm trying to do
Date: Fri, 13 Jan 2012 20:53:39 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:9.0) Gecko/20111222 Thunderbird/9.0

On 01/13/2012 06:49 PM, jfw wrote:
> 
> Am I correct in assuming that the following is doable using M4.

M4 is a Turing complete language, so without reading your question, I
can state that yes, it should be possible.  That said, the devil's in
the details :)

> If so are there M4 implementations of macros available on the web to do this
> sort of thing
> that I can model my m4_lib.m4 code on?

That, I don't know.  autoconf has a pretty good library of m4 macros,
but they are tuned more to shell script generation.

> Here's what I'm trying to do:
> use a library of M4 macros: m4_lib.m4
> use text files {g,h,s}.txt containing general definition of items
> use specific M4 files: {e,g,h,s}_{enum,name,hash}.m4 to generate files from
> the txt files.
> generate .h files: {e,g,h,s}_enum.h, {g,h)_name.h, and s_hash.h.
> 

> macros:
> 
> __in(name,value,flags,comment) definition selected from m4_lib.m4 by flag
> settings

Considering just __in(), I would lay things out so that m4_lib.m4 has
common setup, then specific .m4 files have the appropriate definitions
for the end result file it will be generating.  Going by your example,
that means for converting .txt to enum, you would have enum.m4 contain:

define(`__in', `\tg_$1\t=\t$2,\t$4')dnl

while for converting .txt to name, you would have name.m4 contain:

define(`__in', `\t"$1",')dnl

Then to run the conversions, you would do:

m4 m4_lib.m4 enum.m4 g.txt > g_enum.h
m4 m4_lib.m4 enum.m4 h.txt > h_enum.h
m4 m4_lib.m4 name.m4 g.txt > g_name.h
m4 m4_lib.m4 name.m4 h.txt > h_name.h

Or are you trying to say that __in() should probe the third argument to
decide whether to make an output or skip a line, according to the flags
present in that argument?  In that case, I'd suggest you put this in
m4_lib.m4:

define(`__ENUM', `1')dnl
define(`__NAME', `2')dnl

then in enum.m4:

define(`__in', `ifelse(expr((($3) & __ENUM) == __ENUM), `1',
  `\tg_$1\t=\t$2,\t$4')')dnl

and in name.m4:

define(`__in', `ifelse(expr((($3) & __NAME) == __NAME), `1',
  `\t"$1",')')dnl

You didn't quite show what you wanted s_hash to contain, so it's hard to
say how to write those macros.

> __begbit(initial bit value for __nextbit)

This could live in m4_lib.m4, something like:

define(`__begbit', `define(`__bit', `$1')')dnl

> __nextbit(return 32bit hex representation of value; increase value*2)

define(`__nextbit', `__bit`'define(`__bit',
  format(`0x%x', expr(__bit * 2)))')dnl

> __genbit(named base, begin value (default to last __nextbit),end value)

Here, you're asking for a tough one.  The way you described __begbit,
you plan on passing in the power of 2, which means you have to compute
the log base 2 of __bit; which is doable using bit-wise manipulations in
expr() but not trivial.  I'd suggest that you instead rewrite your .txt
files to pass in the exponent instead of the power of 2, at which point
you then rewrite __nextbit to compute the power of 2.  That is, the sequence

__begbit(3)
__nextbit
__nextbit

would generate 0x00000008 then 0x00000010, with this definition of
__nextbit:

define(`__nextbit', `format(`0x%08x',
  expr(1<<__bit))`'define(`__bit', incr(__bit))')dnl

At which point, your desired implementation of __genbit is based on
using a for loop, as documented in the m4 manual, in your m4_lib.m4:
https://www.gnu.org/software/m4/manual/m4.html#Forloop

define(`forloop', `pushdef(`$1', `$2')_forloop($@)popdef(`$1')')dnl
define(`_forloop',
  `$4`'ifelse($1, `$3', `', `define(`$1', incr($1))$0($@)')')dnl
define(`__genbit',
  `forloop(`__i', ifelse(`$2', `', __bit, `$2'), `$3',
    `\t"$1`'__i",
')dnl')dnl

-- 
Eric Blake   address@hidden    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

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