From 659fc6b55e28740c74d66dbe3bda765d1004a12e Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sun, 27 Feb 2005 21:40:23 +0000 Subject: Implementation of the second expansion in explicit rules, static pattern rules and implicit rules. --- file.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 97 insertions(+), 12 deletions(-) (limited to 'file.c') diff --git a/file.c b/file.c index ae99745..70e5358 100644 --- a/file.c +++ b/file.c @@ -416,12 +416,14 @@ snap_deps (void) { register struct file *f; register struct file *f2; - register struct dep *d; + register struct dep *d, *d1; register struct file **file_slot_0; register struct file **file_slot; register struct file **file_end; - /* Enter each dependency name as a file. */ + /* Perform second expansion and enter each dependency + name as a file. */ + /* We must use hash_dump (), because within this loop we might add new files to the table, possibly causing an in-situ table expansion. */ @@ -429,16 +431,99 @@ snap_deps (void) file_end = file_slot_0 + files.ht_fill; for (file_slot = file_slot_0; file_slot < file_end; file_slot++) for (f2 = *file_slot; f2 != 0; f2 = f2->prev) - for (d = f2->deps; d != 0; d = d->next) - if (d->name != 0) - { - d->file = lookup_file (d->name); - if (d->file == 0) - d->file = enter_file (d->name); - else - free (d->name); - d->name = 0; - } + { + struct dep *new = 0; + struct dep *old = f2->deps; + unsigned int last_dep_has_cmds = f2->updating; + + f2->updating = 0; + f2->deps = 0; + + /* We are going to do second expansion so initialize file + variables for the file. */ + initialize_file_variables (f2, 0); + + for (d = old; d != 0; d = d->next) + { + if (d->name != 0) + { + char *p; + struct dep **d_ptr; + + set_file_variables (f2); + + p = variable_expand_for_file (d->name, f2); + + /* Parse the dependencies. */ + new = (struct dep *) + multi_glob ( + parse_file_seq (&p, '|', sizeof (struct dep), 1), + sizeof (struct dep)); + + if (*p) + { + /* Files that follow '|' are special prerequisites that + need only exist in order to satisfy the dependency. + Their modification times are irrelevant. */ + + struct dep *d; + for (d_ptr = &new; *d_ptr; d_ptr = &(*d_ptr)->next) + ; + ++p; + + *d_ptr = (struct dep *) + multi_glob ( + parse_file_seq (&p, '\0', sizeof (struct dep), 1), + sizeof (struct dep)); + + for (d = *d_ptr; d != 0; d = d->next) + d->ignore_mtime = 1; + } + + /* Enter them as files. */ + for (d1 = new; d1 != 0; d1 = d1->next) + { + d1->file = lookup_file (d1->name); + if (d1->file == 0) + d1->file = enter_file (d1->name); + else + free (d1->name); + d1->name = 0; + } + + /* Add newly parsed deps to f2->deps. If this is the last + dependency line and this target has commands then put + it in front so the last dependency line (the one with + commands) ends up being the first. This is important + because people expect $< to hold first prerequisite + from the rule with commands. If it is not the last + dependency line or the rule does not have commands + then link it at the end so it appears in makefile + order. */ + + if (new != 0) + { + if (d->next == 0 && last_dep_has_cmds) + { + for (d_ptr = &new; *d_ptr; d_ptr = &(*d_ptr)->next) + ; + + *d_ptr = f2->deps; + f2->deps = new; + } + else + { + for (d_ptr = &(f2->deps); *d_ptr; d_ptr = &(*d_ptr)->next) + ; + + *d_ptr = new; + } + } + } + } + + free_dep_chain (old); + } free (file_slot_0); for (f = lookup_file (".PRECIOUS"); f != 0; f = f->prev) -- cgit v1.2.3