[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Implementing 'tr' in GNU Make 3.80
From: |
Dill, John |
Subject: |
Re: Implementing 'tr' in GNU Make 3.80 |
Date: |
Fri, 7 Jan 2005 11:13:33 -0600 |
>Sometimes it's handy to be able to 'tr' inside GNU Make without wasting
>time going to the shell. Here's an implementation that works with GNU
>Make 3.80:
>
># The tr function. Has three arguments:
>#
># $1 The list of characters to translate from
># $2 The list of characters to translate to
># $3 The text to translate
>#
># For example, $(call tr,A B C,1 2 3,CAPITAL) becomes 21PIT1L.
>
>tr = $(eval __t := $3) \
> $(foreach c, \
> $(join $(addsuffix :,$1),$2), \
> $(eval __t := \
> $(subst $(word 1,$(subst :, ,$c)),$(word 2,$(subst :, ,$c)), \
> $(__t))))$(__t)
>
># Common character classes for use with the tr function. Each of
># these is actually a variable declaration and must be wrapped with
># $() or ${} to be used.
>
>[A-Z] := A B C D E F G H I J K L M N O P Q R S T U V W X Y Z #
>[a-z] := a b c d e f g h i j k l m n o p q r s t u v w x y z #
>[0-9] := 0 1 2 3 4 5 6 7 8 9 #
>[A-F] := A B C D E F #
>
># Upper case and lower case functions. Each function has a single
># argument which is the text to alter
>
>uc = $(call tr,$([a-z]),$([A-Z]),$1)
>lc = $(call tr,$([A-Z]),$([a-z]),$1)
>
>.PHONY: all
>all:
> @echo $(call lc,The Quick Brown Fox)
> @echo $(call uc,The Quick Brown Fox)
Very nice. That is actually where I'm heading towards, although instead of
using [A-Z], I was implementing it using character expression classes, a la
colon:=:
[$(colon)upper$(colon)]:=A B C ... X Y Z
[$(colon)lower$(colon)]:=a b c ... x y z
I'm currently trying to figure out a way to incorporate punctuation characters
into the list in a way so that it doesn't interfere with make semantics. The
biggest problem character seems to be space, in that there is no way to
represent it as a single character in a list of characters, not even escaping
helps.
One idea is that instead of using $(word ...), we'd write a wrapper which
expands escaped versions of characters into that character, maybe something
like $(char ...) which will replace something like \space with ' '.
Then I could create some of the other character expression classes like
[$(colon)punct$(colon)]:=\space ! " \hash \dollar \percent & etc...
Then I think this could fit in to your tr framework without too much difficulty.
I think we could expand on the [A-Z] idea, but we would need a custom function
to interpret a regex range item. We could code an ascii numerical encoding to
characters to form ranges. After all, [A-Z] is really character 65 to 90. We
could create a function which translates [A-Z] into asc65 asc90 and generate
indexes to index a list of ascii characters to build using wordlist. I think
it's possible to generalize this [range] concept to a more general level.
John D.