m4-discuss
[Top][All Lists]
Advanced

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

Re: listing currently defined macros


From: Gary V. Vaughan
Subject: Re: listing currently defined macros
Date: Sun, 17 Feb 2008 17:07:45 +0800

Hi Eric!

On 17 Feb 2008, at 04:12, Eric Blake wrote:
I have often found myself wanting a subset of the currently defined macros that matches a regular expression or glob. But there's no easy way to get at it, even with the new m4symbols macro on the head, because you have to
know the names of the subset in advance (the manual documents a way to
double-quote the output of m4symbols, then pass that through a foreach
loop to filter it, but it is not very efficient; and while it can do
regex, it can't do glob matching since m4 currently has no globbing
builtins[1]).  What do others think of the following proposal for
redefining the semantics of m4symbols? Note that since there has been no release with this macro, we can still tweak the semantics before M4 2.0.

ACK.

I think there might be a cleaner way to introduce globbing, simply by
extending the list of regular expression flavours we support.

Note that other builtins which take a list of macros will not change
semantics - they still take literal lists, for several reasons. One, some of them are specified by POSIX (think dumpdef, traceon, popdef) to take
literal lists, with no room for extensions.

That doesn't mean we can't extend those builtins, as long as we don't
break existing usage...

Two, these macros have been in previous M4 releases, so unlike m4symbols,
we can't gratuitously break backwards compatibility.

ACK.  But, again, if we make careful changes (such as how we approached
the changes to the regexp and patsubst macros), it can often save
introducing gratuitous new macros.

And three - simply use m4symbols' proposed powers to generate a literal
list to feed the other macros (similar to how eval can take arbitrary
expressions and turn them into decimal numbers to feed to other macros
like divert that only parse decimal).

Agreed.

m4symbols
m4symbols([`list'], name...)
m4symbols(`glob', pattern...)
m4symbols(`match', [resyntax], pattern...)

With no arguments, list all symbols.

However (breaking my own rule about not introducing additional macros if
at all possible), I think list sorting and filtering are both useful enough
idioms that we should break them out into new builtins so that our users
needn't resort to the hackish things you mention below... which merely
highlight deficiencys in the current language implementation.  Also,
m4symbols proper will be faster in the case where the order of returned
symbols is not important.  So:

 -- Builtin (gnu): m4symbols([NAMES...])
With no arguments, `m4symbols' expands to a unordered, comma- separated list of the names of all currently defined macro. Each macro name is
     quoted.

This contrasts with `dumpdef' (*note Dumpdef::), whose output cannot
     be accessed by `m4' programs.

When given arguments, `m4symbols' returns the unsorted subset of the
     NAMES currently defined, and silently ignores the rest.  This
     macro was added in M4 2.0.

     m4symbols(`ifndef', `ifdef', `define', `define', `ifdef', `undef')
     =>ifdef,define,define,ifdef

 -- Builtin (list): sort(NAME, [...])
Expands to a sorted, comma-separated list of quoted NAME arguments.
     This macro was added in M4 2.0.

sort(m4symbols(`ifndef', `ifdef', `define', `define', `ifdef', `undef'))
     =>define,define,ifdef,ifdef

     The macro `sort' is recognised only with parameters.

 -- Builtin (list): uniq(NAME, [...])
Expands to an unordered, comma-separated list of quoted NAME arguments,
     with only the first occurrence of duplicate consecutive parameters
     listed in the expansion.  This macro was added in M4 2.0.

uniq(m4symbols(`ifndef', `ifdef', `define', `define', `ifdef', `undef'))
     =>ifdef,define,ifdef
uniq(sort(m4symbols(`ifndef', `ifdef', `define', `ifdef', `undef')))
     =>define,ifdef

     The macro `uniq' is recognised only with parameters.

 -- Builtin (list): filter(PATTERN, LIST, [PATSYNTAX])
Expands to an unordered, comma-separated list of quoted LIST elements that match PATTERN, either according to the current RESYNTAX (*note
     Changeresyntax::) or PATSYNTAX if passed.

     define(`dquote', ``$@'')
     =>
     sort(filter(`*def*', dquote(m4symbols), `GLOB'))
     =>define,defn,dumpdef,ifdef,popdef,pushdef,undefine

     The macro `filter' is recognised only with parameters.

I'm sure we can implement several of the m4sugar style list mangling macros eventually, hence I've put these new builtins into a separate list module.

[1] (I guess it would be nice to add a globbing builtin as well. On the other hand, I seem to recall that globs are a subset of regex - ie. you can convert any valid glob into a valid regex, although the converse is
not always possible.  So maybe you could argue that we already have
globbing if you can just translate the pattern correctly).

I think this proposal has that covered.

[2] The current implementation of m4symbols fully sorts the output,
matching the way that dumpdef operates. This can be exploited to perform
sorting of arbitrary lists - for each element in the list, pushdef an
empty macro with a common prefix and the element as a suffix, then pipe
the list through m4symbols for sorting, and post-process the list to
popdef the temporary symbol and remove the prefix.  Not the fastest or
best use of memory in doing the sorting, but since we don't have any other builtin that sorts or even does lexicographic comparisons, it is rather
interesting to consider.


Ick.

But, excellent point that led me to this proposal.  WDYT?

Cheers,
        Gary
--
  ())_.              Email me: address@hidden
  ( '/           Read my blog: http://blog.azazil.net
  / )=         ...and my book: http://sources.redhat.com/autobook
`(_~)_




Attachment: PGP.sig
Description: This is a digitally signed message part


reply via email to

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