diff -r -u --new-file --exclude-from=exclude_diff make-3.81.orig/Makefile.am make-3.81/Makefile.am --- make-3.81.orig/Makefile.am 2006-04-01 08:36:40.000000000 +0200 +++ make-3.81/Makefile.am 2007-07-21 21:16:47.959849200 +0200 @@ -41,7 +41,8 @@ make_SOURCES = ar.c arscan.c commands.c default.c dir.c expand.c file.c \ function.c getopt.c getopt1.c implicit.c job.c main.c \ - misc.c read.c remake.c $(remote) rule.c signame.c \ + misc.c read.c remake.c custom_outofdate.c persistent_state.c \ + $(remote) rule.c signame.c \ strcache.c variable.c version.c vpath.c hash.c EXTRA_make_SOURCES = vmsjobs.c remote-stub.c remote-cstms.c diff -r -u --new-file --exclude-from=exclude_diff make-3.81.orig/commands.c make-3.81/commands.c --- make-3.81.orig/commands.c 2006-02-20 03:14:01.000000000 +0100 +++ make-3.81/commands.c 2007-07-24 01:56:07.221399895 +0200 @@ -46,7 +46,7 @@ { struct dep *d; char *at, *percent, *star, *less; - + #ifndef NO_ARCHIVES /* If the target is an archive member `lib(member)', then $@ is `lib' and $% is `member'. */ @@ -145,6 +145,7 @@ char *qp; char *bp; unsigned int len; + struct dep_ref *uniq_dep_ref, *dr; /* Compute first the value for $+, which is supposed to contain duplicate dependencies as they were listed in the makefile. */ @@ -192,12 +193,15 @@ really matter for the purpose of updating targets, but it might make some names be listed twice for $^ and $?. */ - uniquize_deps (file->deps); + uniquize_deps (file->deps, &uniq_dep_ref); bar_len = 0; - for (d = file->deps; d != 0; d = d->next) - if (d->ignore_mtime) - bar_len += strlen (dep_name (d)) + 1; + for (dr = uniq_dep_ref; dr != 0; dr = dr->next) + { + d = dr->ref; + if (d->ignore_mtime) + bar_len += strlen (dep_name (d)) + 1; + } if (bar_len == 0) bar_len++; @@ -213,8 +217,9 @@ bar_value = xrealloc (bar_value, bar_max = bar_len); bp = bar_value; - for (d = file->deps; d != 0; d = d->next) + for (dr = uniq_dep_ref; dr != 0; dr = dr->next) { + d = dr->ref; char *c = dep_name (d); #ifndef NO_ARCHIVES @@ -257,6 +262,8 @@ bp[bp > bar_value ? -1 : 0] = '\0'; DEFINE_VARIABLE ("|", 1, bar_value); + + free_dep_ref(uniq_dep_ref); } #undef DEFINE_VARIABLE diff -r -u --new-file --exclude-from=exclude_diff make-3.81.orig/custom_outofdate.c make-3.81/custom_outofdate.c --- make-3.81.orig/custom_outofdate.c 1970-01-01 01:00:00.000000000 +0100 +++ make-3.81/custom_outofdate.c 2007-07-26 03:11:19.065876999 +0200 @@ -0,0 +1,80 @@ +/* Custom out of date handling for GNU Make. +Copyright (C) 2007 Free Software Foundation, Inc. +Contributed by Ramón GarcÃa Fernández
+with the support a grant from the Google Summer of Code program 2007 +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation; either version 3, or (at your option) any later version. + +GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +GNU Make; see the file COPYING. If not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ + +#include "make.h" +#include "filedef.h" +#include "custom_outofdate.h" +#include "variable.h" +#include "commands.h" + + +/* Determinate if there are user defined dependencies for target target */ + +int +has_custom_outofdate (struct file *target) +{ + int ret; + struct variable_set_list *save; + save = current_variable_set_list; + initialize_file_variables (target, 0); + set_file_variables (target); + current_variable_set_list = target->variables; + ret = lookup_variable (".OUT_OF_DATE", sizeof (".OUT_OF_DATE") - 1) != NULL; + current_variable_set_list = save; + return ret; +} + +/* Determinate if target is out of date compared to src, using user defined dependencies */ +int +check_custom_outofdate (struct file *target, struct file *src) +{ + int ret = 0; + struct variable_set_list *save; + char *cmd_eval = NULL; + int cmd_eval_len; + struct variable *ood = NULL; + struct variable_set_list *context = NULL; + save = current_variable_set_list; + current_variable_set_list = target->variables; + ood = lookup_variable (".OUT_OF_DATE", sizeof (".OUT_OF_DATE") - 1); + if (ood == NULL) + { + fprintf (stderr, + "Bug: if .OUT_OF_DATE not defined, this function should not have been invoked"); + goto out; + } + set_file_variables (target); + context = create_new_variable_set (); + define_variable_in_set ("<", 1, src->name, + o_automatic, 0, context->set, NILF); + current_variable_set_list = context; + cmd_eval = allocated_variable_expand (ood->value); + cmd_eval_len = strlen (cmd_eval); + ret = (cmd_eval_len > 0); +out: + if (context != NULL) + { + free_variable_set (context); + } + if (cmd_eval != NULL) + { + free (cmd_eval); + } + current_variable_set_list = save; + return ret; +} diff -r -u --new-file --exclude-from=exclude_diff make-3.81.orig/custom_outofdate.h make-3.81/custom_outofdate.h --- make-3.81.orig/custom_outofdate.h 1970-01-01 01:00:00.000000000 +0100 +++ make-3.81/custom_outofdate.h 2007-07-26 03:11:57.774971685 +0200 @@ -0,0 +1,24 @@ +/* Custom out of date for GNU Make. +Copyright (C) 2007 Free Software Foundation, Inc. +Contributed by Ramón GarcÃa Fernández +with the support a grant from the Google Summer of Code program 2007 +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation; either version 3, or (at your option) any later version. + +GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +GNU Make; see the file COPYING. If not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ + +#ifndef CUSTOM_OUTOFDATE_H +#define CUSTOM_OUTOFDATE_H 1 +int check_custom_outofdate (struct file *target, struct file *src); + +int has_custom_outofdate (struct file *target); +#endif diff -r -u --new-file --exclude-from=exclude_diff make-3.81.orig/dep.h make-3.81/dep.h --- make-3.81.orig/dep.h 2006-03-17 15:24:20.000000000 +0100 +++ make-3.81/dep.h 2007-07-24 02:01:13.614657682 +0200 @@ -82,4 +82,12 @@ extern struct dep *read_all_makefiles PARAMS ((char **makefiles)); extern int eval_buffer PARAMS ((char *buffer)); extern int update_goal_chain PARAMS ((struct dep *goals)); -extern void uniquize_deps PARAMS ((struct dep *)); + +struct dep_ref { + struct dep* ref; + struct dep_ref* next; +}; + +extern void uniquize_deps PARAMS ((struct dep *src, struct dep_ref **uniq_dep_ref)); + +extern void free_dep_ref PARAMS ((struct dep_ref *dep_ref)); diff -r -u --new-file --exclude-from=exclude_diff make-3.81.orig/expand.c make-3.81/expand.c --- make-3.81.orig/expand.c 2006-03-15 04:31:30.000000000 +0100 +++ make-3.81/expand.c 2007-06-30 15:48:32.000000000 +0200 @@ -165,7 +165,50 @@ register struct variable *v; char *value; - v = lookup_variable (name, length); + char *dcolon; + struct variable_set_list *context = current_variable_set_list; + struct variable_set_list *save = current_variable_set_list; + + /* if the name is of the form xxx::var, the expand var in the context of target xxx */ + dcolon = lindex(name, name + length, ':'); + if (!(dcolon != NULL && dcolon + 1 < name + length && *(dcolon + 1) == ':')) { + dcolon = NULL; + } + if (dcolon != NULL) { + /* detected :: */ + const char *var_name; + unsigned int var_length; + char *context_name; + const char *context_name_s; + unsigned int context_length; + struct file *context_f; + struct variable_set_list *save; + var_name = dcolon + 2; + var_length = length - (var_name - name); + context_name_s = name; + context_length = dcolon - name; + context_name = xmalloc(context_length + 1); + memcpy(context_name, context_name_s, context_length); + context_name[context_length] = '\0'; + context_f = lookup_file(context_name); + free(context_name); + if (!context_f) { + warn_undefined (context_name_s, context_length); + return o; + } + save = current_variable_set_list; + /* FIXME: This should not be done here, but it appears that the target variables are not + initialized at this stage. A clearner solution should be found */ + initialize_file_variables(context_f, 0); + set_file_variables(context_f); + context = context_f->variables; + current_variable_set_list = context; + v = lookup_variable (var_name, var_length); + current_variable_set_list = save; + } else { + v = lookup_variable (name, length); + } + if (v == 0) warn_undefined (name, length); @@ -174,7 +217,13 @@ if (v == 0 || (*v->value == '\0' && !v->append)) return o; - value = (v->recursive ? recursively_expand (v) : v->value); + if (v->recursive) { + current_variable_set_list = context; + value = recursively_expand(v); + current_variable_set_list = save; + } else { + value = v->value; + } o = variable_buffer_output (o, value, strlen (value)); @@ -298,6 +347,9 @@ Is the resultant text a substitution reference? */ colon = lindex (beg, end, ':'); + if (colon != NULL && colon + 1 < end && *(colon + 1) == ':') { + colon = lindex(colon + 2, end, ':'); + } if (colon) { /* This looks like a substitution reference: $(FOO:A=B). */ @@ -368,6 +420,7 @@ free (value); } } + } if (colon == 0) diff -r -u --new-file --exclude-from=exclude_diff make-3.81.orig/filedef.h make-3.81/filedef.h --- make-3.81.orig/filedef.h 2006-02-11 23:16:04.000000000 +0100 +++ make-3.81/filedef.h 2007-07-23 23:53:37.835594779 +0200 @@ -64,6 +64,9 @@ short int update_status; /* Status of the last attempt to update, or -1 if none has been made. */ + struct hash_table persistent_state; /* Storage of persistent variables + associated with this target */ + enum cmd_state /* State of the commands. */ { /* Note: It is important that cs_not_started be zero. */ cs_not_started, /* Not yet started. */ diff -r -u --new-file --exclude-from=exclude_diff make-3.81.orig/function.c make-3.81/function.c --- make-3.81.orig/function.c 2006-04-01 08:36:40.000000000 +0200 +++ make-3.81/function.c 2007-07-24 02:02:05.305771879 +0200 @@ -23,6 +23,7 @@ #include "job.h" #include "commands.h" #include "debug.h" +#include "persistent_state.h" #ifdef _AMIGA #include "amiga.h" @@ -1387,6 +1388,45 @@ return o; } + + + +static char * +func_changed_value (char *o, char **argv, const char *funcname UNUSED) +{ + const char *target = argv[0]; + const char *var_name = argv[1]; + const char *new_value = argv[2]; + char *old_value = NULL; + unsigned int old_value_size = 0; + char *result; + unsigned int new_value_size = strlen(new_value); + load_variable(target, var_name, &old_value, &old_value_size); + /* filename will be directory(target)/.targetname.varname */ + /* scaping special chars from varname */ + result = o; + if (old_value_size == new_value_size && + (old_value_size == 0 || memcmp(old_value, new_value, old_value_size) == 0)) + result = o; + else + { + /* Arrange target to write persistent values after its compilation */ + struct file* target_file = lookup_file(target); + if (target == NULL) + fprintf (stderr, "changed-value: unknown target %s\n", target); + else + { + schedule_store_variable (target_file, var_name, new_value, new_value_size); + result = variable_buffer_output (o, "true", sizeof("true")); + } + } + + if (old_value != NULL) + free(old_value); + return result; +} + + /* \r is replaced on UNIX as well. Is this desirable? */ @@ -2081,6 +2121,7 @@ { STRING_SIZE_TUPLE("and"), 1, 0, 0, func_and}, { STRING_SIZE_TUPLE("value"), 0, 1, 1, func_value}, { STRING_SIZE_TUPLE("eval"), 0, 1, 1, func_eval}, + { STRING_SIZE_TUPLE("changed-value"), 3, 3, 1, func_changed_value}, #ifdef EXPERIMENTAL { STRING_SIZE_TUPLE("eq"), 2, 2, 1, func_eq}, { STRING_SIZE_TUPLE("not"), 0, 1, 1, func_not}, diff -r -u --new-file --exclude-from=exclude_diff make-3.81.orig/persistent_state.c make-3.81/persistent_state.c --- make-3.81.orig/persistent_state.c 1970-01-01 01:00:00.000000000 +0100 +++ make-3.81/persistent_state.c 2007-07-26 03:13:00.711370343 +0200 @@ -0,0 +1,272 @@ +/* Saving and loading persistent state - implementation for GNU Make. +Copyright (C) 2007 Free Software Foundation, Inc. +Contributed by Ramón GarcÃa Fernández +with the support a grant from the Google Summer of Code program 2007 +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation; either version 3, or (at your option) any later version. + +GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +GNU Make; see the file COPYING. If not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ + + +#include "make.h" +#include "filedef.h" +#include "persistent_state.h" + + +/* FIXME: duplicated code from function.c. Move this to a header file */ + +#ifdef VMS +# define IS_PATHSEP(c) ((c) == ']') +#else +# ifdef HAVE_DOS_PATHS +# define IS_PATHSEP(c) ((c) == '/' || (c) == '\\') +# else +# define IS_PATHSEP(c) ((c) == '/') +# endif +#endif + + + + +/* Grow a buffer 'added_size' bytes */ +static void +enlarge_buffer (char **buffer, + unsigned int *alloc_len, unsigned int *len, + unsigned int added_size) +{ + *len += added_size; + if (*len > *alloc_len) { + *alloc_len = 2*(*alloc_len) > *len ? 2*(*alloc_len) : *len; + *buffer = xrealloc(*buffer, *alloc_len); + } +} + +/* + Write a char in radix 16 to a buffer, that is, if char is 0xab, + then buffer[0] = a, buffer[1] = b + */ +static void +write_hex (char c, char *buffer) +{ + const static char hexchars[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F'}; + buffer[0] = hexchars[(c & 0xF0) >> 4]; + buffer[1] = hexchars[c & 0xF]; +} + +/* Determinate the filename for a state file + This uses the format [target directory]/.[target name].[var name] + var name is encoded in case it contains path characters + + The caller must free filename +*/ + +static char* +filename_state (const char *target, const char *var_name) +{ + unsigned int target_len = strlen(target); + unsigned int var_len = strlen(var_name); + const char* target_dir = target; + char* result = NULL; + unsigned int result_len, result_alloc_len; + unsigned int target_dir_len; + int i; + int last_written; + target_dir_len = target_len; + while (target_dir_len > 0) + { + if (IS_PATHSEP(target_dir[target_dir_len - 1])) + break; + target_dir_len--; + } + result = xmalloc(target_len + 2); + result_len = target_dir_len; + result_alloc_len = target_len + 2; + memcpy(result, target, target_dir_len); + last_written = target_dir_len; + enlarge_buffer(&result, &result_alloc_len, &result_len, 1); + result[last_written] = '.'; + last_written = result_len; + enlarge_buffer(&result, &result_alloc_len, &result_len, target_len - target_dir_len); + memcpy(&result[last_written], &target[target_dir_len], target_len - target_dir_len); + last_written = result_len; + enlarge_buffer(&result, &result_alloc_len, &result_len, 1); + result[last_written] = '.'; + last_written = result_len; + for (i = 0; i < var_len; i++) + { + if (IS_PATHSEP(var_name[i]) || var_name[i] == '%') + { + last_written = result_len; + enlarge_buffer(&result, &result_alloc_len, &result_len, 3); + result[last_written] = '%'; + write_hex(var_name[i], &result[last_written + 1]); + } + else + { + last_written = result_len; + enlarge_buffer(&result, &result_alloc_len, &result_len, 1); + result[last_written] = var_name[i]; + } + } + last_written = result_len; + enlarge_buffer(&result, &result_alloc_len, &result_len, 1); + result[last_written] = '\0'; + return result; +} + +static const unsigned int PERSISTENT_VAR_BUCKETS = 16; + +struct persistent_var +{ + unsigned int name_len; + char *name; + unsigned int value_len; + char *value; +}; + +static unsigned long +persistent_var_hash_1 (const void *keyv) +{ + const struct persistent_var *v = (const struct persistent_var *) keyv; + return_STRING_N_HASH_1(v->name, v->name_len); +} + +static unsigned long +persistent_var_hash_2 (const void *keyv) +{ + const struct persistent_var *v = (const struct persistent_var *) keyv; + return_STRING_N_HASH_2(v->name, v->name_len); +} + +static int +persistent_var_hash_cmp (const void *xv, const void *yv) +{ + const struct persistent_var *v1 = (const struct persistent_var *) xv; + const struct persistent_var *v2 = (const struct persistent_var *) yv; + int result = v1->name_len - v2->name_len; + if (result != 0) + return result; + return_STRING_N_COMPARE(v1->name, v2->name, v1->name_len); +} + +/* Arrange that a persistent value will be stored after the successful + compilation of a target */ +void +schedule_store_variable (struct file *target, + const char *var_name, const char *value, unsigned int value_len) +{ + struct hash_table *persistent_state = &target->persistent_state; + struct persistent_var key; + struct persistent_var *var; + struct persistent_var **slot; + unsigned int name_len; + if (persistent_state->ht_vec == NULL) + hash_init(persistent_state, PERSISTENT_VAR_BUCKETS, + persistent_var_hash_1, persistent_var_hash_2, persistent_var_hash_cmp); + name_len = strlen(var_name); + key.name = (char*) var_name; + key.name_len = name_len; + slot = (struct persistent_var**) hash_find_slot(persistent_state, &key); + if (!HASH_VACANT(*slot)) + { + fprintf(stderr, "Warning: persistent variable name %s of target %s overwritten\n", + var_name, target->name); + free((*slot)->value); + var = *slot; + } + else + { + var = (struct persistent_var*) xmalloc(sizeof(struct persistent_var)); + hash_insert_at(persistent_state, var, slot); + var->name_len = name_len; + var->name = xmalloc(var->name_len + 1); + memcpy(var->name, var_name, var->name_len + 1); + var->value = xmalloc(value_len); + memcpy(var->value, value, value_len); + var->value_len = value_len; + + persistent_state->ht_fill++; + } + +} + + +/* Load a persistent variable. Returns a malloced string variable, that should be freed by caller */ +void +load_variable (const char *target, + const char *var_name, char **value, unsigned int *value_len) +{ + char *filename; + FILE *file; + unsigned int value_alloc_size = 0; + + filename = filename_state (target, var_name); + file = fopen (filename, "r"); + if (file == NULL && errno != ENOENT) + fprintf (stderr, "changed_value: could not open state file %s: %s\n", + filename, strerror(errno)); + *value = NULL; + if (file != NULL) + { + while (1) + { + int value_alloc_size_2 = BUFSIZ + value_alloc_size; + if (*value != NULL) + *value = xrealloc(*value, value_alloc_size_2); + else + *value = xmalloc(value_alloc_size_2); + int nread; + nread = + fread(&(*value)[*value_len], 1, value_alloc_size_2 - value_alloc_size, file); + if (nread < 0) + { + fprintf (stderr, "changed_value: error reading state file %s: %s\n", + filename, strerror(errno)); + break; + } + *value_len += nread; + value_alloc_size = value_alloc_size_2; + if (*value_len < value_alloc_size) + break; + } + fclose(file); + } + +} + + +static void save_persistent_var_map_fn (void const *item, void *arg) +{ + const struct persistent_var *v = (const struct persistent_var*) item; + const char *target_name = (const char *) arg; + char *var_filename = filename_state (target_name, v->name); + FILE *var_file = fopen(var_filename, "w"); + if (var_file == NULL) { + fprintf(stderr, "Cannot write to state file %s\n", var_filename); + goto out; + } + fwrite(v->value, 1, v->value_len, var_file); +out: + if (var_file != NULL) + fclose(var_file); + free(var_filename); + +} + +/* Save to disk the variables previously recorded with schedule_store_variable. + This rouble should be run after a successful compilation of a target */ +void +save_persistent_variables (struct file *target) +{ + hash_map_arg(&target->persistent_state, save_persistent_var_map_fn, target->name); +} diff -r -u --new-file --exclude-from=exclude_diff make-3.81.orig/persistent_state.h make-3.81/persistent_state.h --- make-3.81.orig/persistent_state.h 1970-01-01 01:00:00.000000000 +0100 +++ make-3.81/persistent_state.h 2007-07-26 03:13:09.685001359 +0200 @@ -0,0 +1,37 @@ +/* Saving and loading persistent stat for GNU Make. +Copyright (C) 2007 Free Software Foundation, Inc. +Contributed by Ramón GarcÃa Fernández +with the support a grant from the Google Summer of Code program 2007 +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation; either version 3, or (at your option) any later version. + +GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +GNU Make; see the file COPYING. If not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ + +#ifndef PERSISTENT_STATE_H +#define PERSISTENT_STATE_H + + + +void +schedule_store_variable(struct file *target, + const char *var_name, const char *new_value, unsigned int new_value_size); + + +void +load_variable(const char *target, + const char *var_name, char **variable, unsigned int *variable_length); + + +void +save_persistent_variables(struct file *target); + +#endif diff -r -u --new-file --exclude-from=exclude_diff make-3.81.orig/read.c make-3.81/read.c --- make-3.81.orig/read.c 2006-03-17 15:24:20.000000000 +0100 +++ make-3.81/read.c 2007-07-24 02:03:04.393757636 +0200 @@ -1716,10 +1716,11 @@ void -uniquize_deps (struct dep *chain) +uniquize_deps (struct dep *chain, struct dep_ref **uniq_dep_ref) { struct hash_table deps; - register struct dep **depp; + struct dep *dep; + struct dep_ref **dep_ref; hash_init (&deps, 500, dep_hash_1, dep_hash_2, dep_hash_cmp); @@ -1727,26 +1728,39 @@ really matter for the purpose of updating targets, but it might make some names be listed twice for $^ and $?. */ - depp = &chain; - while (*depp) + dep = chain; + dep_ref = uniq_dep_ref; + while (dep) { - struct dep *dep = *depp; struct dep **dep_slot = (struct dep **) hash_find_slot (&deps, dep); if (HASH_VACANT (*dep_slot)) { hash_insert_at (&deps, dep, dep_slot); - depp = &dep->next; - } - else - { - /* Don't bother freeing duplicates. - It's dangerous and little benefit accrues. */ - *depp = dep->next; + struct dep_ref* link = (struct dep_ref*) xmalloc(sizeof(struct dep_ref)); + link->ref = dep; + *dep_ref = link; + dep_ref = &link->next; } + dep = dep->next; } + *dep_ref = NULL; hash_free (&deps, 0); } + +void +free_dep_ref (struct dep_ref *dep_ref) +{ + struct dep_ref *link = dep_ref, *next; + + while (link != NULL) + { + next = link->next; + free(link); + link = next; + } +} + /* Record target-specific variable values for files FILENAMES. TWO_COLON is nonzero if a double colon was used. diff -r -u --new-file --exclude-from=exclude_diff make-3.81.orig/remake.c make-3.81/remake.c --- make-3.81.orig/remake.c 2006-03-20 03:36:37.000000000 +0100 +++ make-3.81/remake.c 2007-07-23 22:34:20.847303169 +0200 @@ -23,6 +23,8 @@ #include "dep.h" #include "variable.h" #include "debug.h" +#include "custom_outofdate.h" +#include "persistent_state.h" #include