helpGNU M4 - Support: sr #105855, Multi-op patsubst() and translit()


sr #105855: Multi-op patsubst() and translit()

Submitter:  Daniel Richard G. <iskunk>
Submitted:  Fri 11 May 2007 04:21:57 AM UTC
Category:  None Priority:  5 - Normal
Severity:  1 - Wish Status:  None
Privacy:  Public Assigned to:  None
Open/Closed:  Open Operating System:  GNU/Linux
* Mandatory Fields

Add a New Comment (Rich Markup)

Comment Type & Canned Response:


Thu 24 May 2007 03:38:37 AM UTC, comment #3: 

Also, have a look at the m4_bpatsubsts() macro in Autoconf's m4sugar.m4. It's basically the same idea, but comes with a major caveat:

# I would have liked to name this macro `m4_bpatsubst', unfortunately,
# due to quotation problems, I need to double quote $1 below, therefore
# the anchors are broken :(  I can't let users be trapped by that.

This would appear to be a pretty strong confirmation that a multi-op patsubst() cannot be properly achieved by way of composites.

Daniel Richard G. <iskunk>
Sat 12 May 2007 01:39:12 AM UTC, comment #2: 

(typeytype in the new-and-improved translit macro)
translit([abc123], [[a-z]], [[A-Z]], [[0-4]], [[5-9]])
=> ABC678
translit([abc)123], [[a-z]], [[A-Z]], [[0-4]], [[5-9]])
=> /opt/m4/bin/m4:stdin:7: Warning: translit: too few arguments: 1 < 2

Robustness against meta-characters was the issue for me.

I didn't go so far as to try a recursive macro, but there were two other approaches I was experimenting with. First, iteratively operating on a temp-variable macro...

pushdef([tmp], [$1])
define([tmp], patsubst(tmp, [pat1], [rep1]))
define([tmp], patsubst(tmp, [pat2], [rep2]))

Second, just nesting the patsubst() calls:

patsubst(patsubst(patsubst([$1], [pat1], [rep1]), [pat2], [rep2]), ...)

The problem with all these approaches is in quoting the text argument to patsubst. [$1] works perfectly well, but after that, you can't quote the argument, or the builtin operates directly on macro names ("tmp" or "patsubst" or "translit").

With a multi-op patsubst()/translit(), [$1] would be all you need. That's my "real reason" for wanting it, though of course code efficiency and parallelism to ifelse() figure in there too.

(Oh, by the way, as things currently are, I couldn't even use a recursive macro. $@ expands to quoted arguments separated by commas---but I'm using a different argument separator, and this variable doesn't play along.)

Daniel Richard G. <iskunk>
Fri 11 May 2007 12:33:05 PM UTC, comment #1: 

Why can't you write your own recursive macro that does this?  translit should be easy:

# translit(string, regex1, replace1, regex2, replace2, ...)
pushdef([translit], [ifelse(eval([$# <= 3]), 1,
  [builtin([translit], $@)],
  [translit(builtin([translit], [$1], [$2], [$3]),

patsubst is a bit harder, since 2.0 is adding the optional resyntax parameter (you almost need to reverse the argument order, and specify the resyntax parameter before the list, since it is difficult in recursive algorithms to get the last argument on the first iteration of action), but still something you should be able to write a wrapper for.  I'm not sure I see modifying the builtin to do this, if we can't prove that there is an efficiency issue that can't be worked around by merely writing wrappers around the existing builtins.

Eric Blake <ericb>
Project Administrator
Fri 11 May 2007 04:21:57 AM UTC, original submission:  

A wish for m4 2.0: patsubst() and translit() builtins that can do more than one operation in a single call. Right now, it's awkward to chain together multiple invocations of these, and the quoting/robustness issues can get very hairy.

I'd like to see patsubst()/translit() gain a multi-argument semantic like ifelse(), where one could invoke e.g.

  patsubst(`$1', `meow', `woof', `apple', `orange', `blue', `red', `POSIX_EXTENDED')

Daniel Richard G. <iskunk>


(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:

No files currently attached


Depends on the following items: None found

Items that depend on this one: None found


Carbon-Copy List
  • -email is unavailable- added by ericb (Posted a comment)
  • -email is unavailable- added by iskunk (Submitted the item)

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.





    No changes have been made to this item

    Back to the top

    Powered by Savane 3.9