RE: basename function does nothing when it appears in prerequisites

2001-09-09 Thread Matt Swift

I understand the explanation, but I do not understand why, if it applies to
the $(basename) function, it does not apply to the $(addsuffix) function.
If addsuffix behaved like basename, then the dependency list for the target
foo.yy would be ".zz" instead of "foo.yy.zz" (which it is by experiment --
that's why this was in the test makefile).


> %% Manoj Srivastava <[EMAIL PROTECTED]> writes:
>
>   ms> The following sample makefile should not produce the error it does
>   ms> produce (output follows the makefile).  The $(basename ...)
>   ms> function should work when it appears in the prerequisites section
>   ms> of a rule, but it does nothing.
>
> No, it shouldn't.  Make is behaving correctly.
>
> All variable and function expansion for targets and prerequisite lists
> occurs when the makefile is read in, well before any sort of pattern
> expansion occurs; so these functions are operating on the static string
> "%", not the string it will expand to after pattern matching.
>
> See the GNU make manual for discussion of how make reads makefiles and
> when different parts of the makefile are expanded.
>
>   ms> foo.yy: %: $(addsuffix .zz, %)
>
>   ms> foo.xx: %: $(basename %)



___
Bug-make mailing list
[EMAIL PROTECTED]
http://mail.gnu.org/mailman/listinfo/bug-make



Re: basename function does nothing when it appears in prerequisites

2001-09-09 Thread Matt Swift


>> On Sun, 9 Sep 2001 16:18:15 -0400, Paul D Smith <[EMAIL PROTECTED]> wrote:

P> In this case, what is basename of "%"?  Just "%" itself, so you end up
P> with this:

P>   foo.xx: %: %


Thank you for the clear explanation.  


It is not the first time you have provided one for me!  My memory is
short, but my files are long.  We had a long and illuminating
corespondence on very similar matters in feb-mar 1999, though of
course I did not recognize the current issue as similar until now --
the truth about % seems to drain from my head over time.

I have two further comments.  

1) In our previous correspondence you explained how the design of make
   forbids using % in variables and function arguments.  It does seem
   to me, however, that a makefile like the following could be
   processed sequentially in one pass without ambiguity.  It seems to
   me that $(remote-%-home) could in fact be resolved more easily than
   make-%-manifests, which make does resolve.  Perhaps the difficulty
   is in distinguishing the OK cases from the problematic ones.  I
   don't need a reply to this, it is just a thought after reviewing
   our corresondence on the general issue.

remote-data-home = buzz  # or := if better
remote-web-home = booze
remote-lists-home = boss

targets = data web lists
$(addsuffix .test, $(targets)): %.test: make-%-manifests $(remote-%-home)



2) On behalf of those with short memories like mine, I have the
   following suggestions for emending the Make manual.

The top of node "Functions" in make.info (4 April 2000) says this:

   "Functions" allow you to do text processing in the makefile to
compute the files to operate on or the commands to use.  You use a
function in a "function call", where you give the name of the function
and some text (the "arguments") for the function to operate on.  The
result of the function's processing is substituted into the makefile at
the point of the call, just as a variable might be substituted.

The phrase "at the point of the call" is ambiguous (it could be time
or space).  Neither interpretation adds any information -- when or
where else could the substitution be?  I suggest the following revised
final sentence.  You may find it too verbose; what I think is
important is the cross-reference.  (I'm not sure how the text of the
cross-ref should/does read in texinfo format, though.)

The result of the function's processing is substituted into the
makefile [*] when `make' expands the construct in which it appears.
Some constructs are expanded when `make' first reads the makefile
and others are expanded later.  (For details, see *note How `make'
Reads a Makefile: Reading Makefiles.) 


[*] If you think retaining mention of the "point in space" is
important, I suggest adding "where the function appears" here.


I also recommend adding a cross reference to the "Reading Makefiles"
node somewhere in this paragraph in the node "Pattern Rules":

   Note that expansion using `%' in pattern rules occurs *after* any
variable or function expansions, which take place when the makefile is
read.  *Note How to Use Variables: Using Variables, and *Note Functions
for Transforming Text: Functions.

You might consider adding a sentence like the following, which
explains the consequences: `%' in a pattern rule is therefore treated
as a literal `%' when it appears in a function argument or variable
name.

___
Bug-make mailing list
[EMAIL PROTECTED]
http://mail.gnu.org/mailman/listinfo/bug-make



functions `index' and `foreachstar'

2002-12-15 Thread Matt Swift

I just put a patch onto Savannah with two new experimental functions
`index' and `foreachstar' (dumbly named!), and I am writing this mail
to explain it a bit.

Well, I started to explain, and I ended up rambling and theorizing --
and not just a little, and now I want to go make sure Miami loses to
Oakland, so I'm going to give a brief explanation :)

`$(index FIND,IN)'
 Searches IN for an occurrence of FIND.  If it occurs, the value of the 
function is
 the index of IN in FIND, starting with 1; otherwise, the value is 0.

 Compare the function `findstring'.

 You can use this function in a conditional to test for the presence of a
 specific substring in a given string.  Thus, the two examples,

  $(index a,a b c)
  $(index a,b c)

 produce the values `1' and `0', respectively.

 When $(index $(a), $(x)) is not `0', 
 $(word $(index $(a), $(x)), $(x)) is always equal to $(a).


   `$(foreachstar ...)'
   Like foreach, but separate components with newline instead of space, for use 
with $(eval ..).
   I really need to think of a better name for this function!




I wrote the new functions before seeing the thread last month about
the bug in the `eval' function and the debate about it.  I think I
have been after the same sort of goal.  I've just now installed the
post-3.80 patches on my system, and soon will experiment to see what
might work now that didn't work before.

When I read about the new features in 3.80 and began to experiment,
one of the tasks I set for myself was to write a target that caused
the name and value of every variable to be echoed in a simple way.

It proved too hard for me!  Can anyone do this?  It's typical, I
think, of what one wants `eval' to help do.

I wrote the two functions `index' and `foreachstar' to try to take
`eval' that last few yards to being the feature of our dreams.

Basically, the `index' function, working with `word' or `wordlist',
can help implement the kind of record-structure that seems to me is
the main stumbling block, insofar as before `eval' it could only be
done if the data themselves had a structure such that %-patterns would
inherently provide your array/record structure.  For example:

targets  = publicprivate professional
target.machines  = webserver.com localhost   toolndie.com
target.porno-p   = noyes no
target.dirs  = web   web/me  web/me/work


# argument TARGET, expands to the stamp associated with it
stamp-of  = $(word $(index $(1), $(targets)), $(target.stamps))
target.stamps = $(foreach t, $(target), $(call stamp-of, $(t)))

(I haven't worked out this example carefully enough to assure that it
can't be done another way, but if it can, I've almost definitely
proved that I did need `index' in situations that are about like this.)


Below is a test Makefile and its output.  The error at the end comes
up when Make tries to print out a variable value that has a newline in
it -- the evaluator doesn't read past the newline.  That's a problem
to resolve.

(Incidentally, I run with "env -i" because something weird is going on
with Make having variables defined after my shell functions -- I've
submitted a bug report to Debian, but it may affect you if you try
this at home.)



begin Makefile


# testing new functions $(index ...) and $(foreach* ...)

nums = one two three four five

all: index foreach dumpvars

index:
@echo "triplets are:"
@echo '  $$(index ...)'
@echo '  expected result of $$(index ...)'
@echo '  $$(findstring ...) for comparison'
@echo
@echo 'blorkle! I don'"'"'t like how $$(findstring ...) works!'
@echo
@echo --
@echo "[$(index one, $(nums))]"
@echo "[1]"
@echo "[$(findstring one, $(nums))]"
@echo --
@echo "[$(index bobo, $(nums))]"
@echo "[0]"
@echo "[$(findstring bobo, $(nums))]"
@echo --
@echo "[$(index five, $(nums))]"
@echo "[5]"
@echo "[$(findstring five, $(nums))]"
@echo --
@echo "[$(index on, $(nums))]"
@echo "[0]"
@echo "[$(findstring on, $(nums))]"
@echo --
@echo "[$(index fo, $(nums))]"
@echo "[0]"
@echo "[$(findstring fo, $(nums))]"
@echo --
@echo "[$(index hree, $(nums))]"
@echo "[0]"
@echo "[$(findstring hree, $(nums))]"
@echo --
@echo "[$(index ne tw, $(nums))]"
@echo "[0]"
@echo "[$(findstring ne tw, $(nums))]"
@echo --

define doit
@echo $(1)
endef

# eval has to deal with a whole rule etc or it barfs

# can't have comments beggining at boln in this def: "missing separator"
# this line ditto:
#   $(foreachstar x, $(nums),\t@echo $(x))

define fofo
foreach:
@echo "should see \"$(nums)\" one per line"
@e