Hello! Given this input:
f0 = $(foreach s,foobar,$(firstword $s:)) e0 = $(foreach s,foobar,$(eval $s:)) f1 = $(foreach s,foobar, $(firstword $s:)) e1 = $(foreach s,foobar, $(eval $s:)) f2 = $(foreach s,foobar, $(firstword $s:)) e2 = $(foreach s,foobar, $(eval $s:)) all: @echo f0 == $(f1) @echo f1 == $(f1) @echo f2 == $(f2) @echo e0 == $(e0) @echo e1 == $(e1) @echo e2 == $(e2) `make all' responds with the following: f0 == foobar: f1 == foobar: f2 == foobar: e0 == e1 == f e2 == fo I certainly did not expect this! All built-in functions *except* `eval' work, when used inside the body of `foreach', as one would expect. The reason is that all the other `func_*' functions in functions.c pass its `o' pointer to variable_buffer_output, but func_eval() does not and, in eval(), a new `variable_buffer' is created which knows nothing about the incremented offset of the original `o' wrt the previous `variable_buffer'. I think that this is a bug, and tried to fix it. I hope my changes do not break anything, although I had to change the syntax of important functions. My new `make' has already successfully built emacs-21.2 and make-3.80. A demonstration of the power of `eval' after this fix: toomas@esimene:~ $ cat Makefile What = $(what) $(foreach s,$(what), \ $(eval prev = $(this)) \ $(eval this = $s) \ $(eval What = $(wordlist 2,$(words $(What)),$(What))) \ $(eval $(this): $(prev))) $(what): @echo making $@ from $^ toomas@esimene:~ $ make.orig what="a b c d e" e Makefile:2: *** target pattern contains no `%'. Stop. toomas@esimene:~ $ make what="a b c d e" e making a from making b from a making c from b making d from c making e from d toomas@esimene:~ $ This is precisely the kind of thing I dreamed of being able to do with the many-rumoured `eval' when 3.80 was not released yet! The changed read_makefile() no longer checks the value returned by eval(), but this should be ok, because when eval() returned at all, it always returned 1 anyway. Thanks for the wonderful program! Toomas. --- ./dep.h.orig Thu Oct 24 22:34:42 2002 +++ ./dep.h Thu Oct 24 22:31:58 2002 @@ -73,6 +73,6 @@ extern struct dep *copy_dep_chain PARAMS ((struct dep *d)); extern struct dep *read_all_makefiles PARAMS ((char **makefiles)); -extern int eval_buffer PARAMS ((char *buffer)); +extern char *eval_buffer PARAMS ((char *o, char *buffer)); extern int update_goal_chain PARAMS ((struct dep *goals, int makefiles)); extern void uniquize_deps PARAMS ((struct dep *)); --- ./function.c.orig Thu Oct 24 22:34:52 2002 +++ ./function.c Thu Oct 24 22:32:01 2002 @@ -1281,9 +1281,7 @@ char **argv; const char *funcname; { - eval_buffer (argv[0]); - - return o; + return eval_buffer (o, argv[0]); } --- ./read.c.orig Thu Oct 24 22:34:48 2002 +++ ./read.c Thu Oct 24 22:32:04 2002 @@ -124,7 +124,7 @@ static struct dep *read_makefiles = 0; static int eval_makefile PARAMS ((char *filename, int flags)); -static int eval PARAMS ((struct ebuffer *buffer, int flags)); +static char *eval PARAMS ((char *o, struct ebuffer *buffer, int flags)); static long readline PARAMS ((struct ebuffer *ebuf)); static void do_define PARAMS ((char *name, unsigned int namelen, @@ -281,7 +281,6 @@ struct ebuffer ebuf; const struct floc *curfile; int makefile_errno; - int r; ebuf.floc.filenm = filename; ebuf.floc.lineno = 1; @@ -376,23 +375,23 @@ curfile = reading_file; reading_file = &ebuf.floc; - r = eval (&ebuf, !(flags & RM_NO_DEFAULT_GOAL)); + eval (0, &ebuf, !(flags & RM_NO_DEFAULT_GOAL)); reading_file = curfile; fclose (ebuf.fp); free (ebuf.bufstart); - return r; + return 1; } -int -eval_buffer (buffer) +char * +eval_buffer (o, buffer) + char *o; char *buffer; { struct ebuffer ebuf; const struct floc *curfile; - int r; /* Evaluate the buffer */ @@ -405,11 +404,11 @@ curfile = reading_file; reading_file = &ebuf.floc; - r = eval (&ebuf, 1); + o = eval (o, &ebuf, 1); reading_file = curfile; - return r; + return o; } @@ -423,8 +422,9 @@ Returns 1 if FILENAME was found and read. Returns 2 if FILENAME was read, and we kept a reference (don't free it). */ -static int -eval (ebuf, set_default) +static char * +eval (o, ebuf, set_default) + char *o; struct ebuffer *ebuf; int set_default; { @@ -910,7 +910,7 @@ break; } - p2 = variable_expand_string(NULL, lb_next, len); + p2 = variable_expand_string(o, lb_next, len); while (1) { lb_next += len; @@ -1211,7 +1211,7 @@ free ((char *) commands); - return 1; + return o; } _______________________________________________ Bug-make mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-make