Sun 08 Jan 2006 04:36:42 AM UTC, original submission:
i will try to explain my feature-request by means of an example:
consider putting ldap distinguished names (which always contain at least one comma) into m4 macros:
define(`basedn', `dc=expample,dc=com')
define(`rootdn', `cn=manager,'basedn)
results in a
m4: Warning: Excess arguments to built-in `define' ignored
of course, we could
define(`basedn', ``dc=expample,dc=com'')
define(`rootdn', `cn=manager,'basedn)
to get the desired
rootdn -> cn=manager,dc=example,dc=com
but then we must know in advance, how many quote-removals a
macro will undergo during macro expansion. but what if this depends on some facts unknown at the time of writing these macros? for example, we want to define a recursive macro which converts all users from /etc/passwd into ldap user-dn's:
define(`uiddn', `ou=people,'basedn)
define(`nextdn', `ifdef(`list',
`define(`list', list`:uid=$1,'uiddn)list',
`define(`list', `uid=$1,'uiddn)list')')
now we can collect all user-dn's:
define(`all', `esyscmd(cat /etc/passwd|cut -d: -f1|
sed -e "s/^/`next'(/;s/$/)/")')
and would get the list of user-dn's with
all
... if there would be a way to disable the syntactic role of ',' as separator of macro parameters because the number of quote-removals the comma-containing "list" macro undergoes when "all" is expanded, depends on the number of lines the "esyscmd" returns and, therefore, we can't insert a suitable amount of quotes at design-time.
(if you exchange ',' with an other character, say '_', then the above macros would work fine, ... but, of course, then you won't get syntactical correct ldap dn's.)
for the moment the only thing (at least the only thing i can think of) we can do is to define macros
define(`protect', `esyscmd(`echo "$*"|tr "," ";"')')
define(`unprotect', `esyscmd(`echo "$*"|tr ";" ","')')
and change the above into
define(`uiddn', `protect(`ou=people,'basedn)')
define(`nextdn', `ifdef(`list',
`define(`list', protect(list`:uid=$1,'uiddn))list',
`define(`list', protect(`uid=$1,'uiddn))list')')
to get the list with
unprotect(all)
which works quite well ... but now ';' mustn't appear in the parameters so that this solution is at least not a general one. in a next step we can make the ';' flexible by introducing a new macro
define(`delim', `;')
and use this inside the protect() and unprotect() macros ...
i hope these rather lengthly explaination could convince you that a more flexible (i.e., changeable at runtime) syntax scheme for m4 would rather useful -- and prior to version 1.4 there had been a (now obviously abandoned) builtin "changesyntax" which seemed to do exactly these things.
by the way, if you take a look at tex's concept of reassigning category codes of input tokens (which is inside the token-based world of tex the same as exchanging characters of particular syntactic roles in the character-based world of m4), you will find that this concept greatly enlarges the expressiveness (and, therefore, the application domain) of a macro language.
|