(eval_makefile): deal with new parent_records paremeter for API consistancy, (eval): assign related parent_records to target variable, and construct tempoaray parent_records when ifdef/ifeq conditional_line is parsed. (conditional_line): when ifdef/ifeq conditional_line is encountered, construct tempoaray parent_records for later dependency chain assignment for the target variable.
Signed-off-by: Macpaul Lin <macp...@gmail.com> --- Changes for v2: - (eval): fix the problem of mapping the same parent_records set to multiple variable in the same ifdef/ifeq depth. - (conditional_line): add if_cmds->depth support. read.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 99 insertions(+), 10 deletions(-) diff --git a/read.c b/read.c index 6ac66f4..4311195 100644 --- a/read.c +++ b/read.c @@ -142,7 +142,11 @@ static void do_undefine (char *name, enum variable_origin origin, struct ebuffer *ebuf); static struct variable *do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf); -static int conditional_line (char *line, int len, const gmk_floc *flocp); +struct parent_record *dup_parent_records (struct parent_record **dst_pr, + struct parent_record *src_pr); +void free_parent_record (struct parent_record *pr); +static int conditional_line (char *line, int len, const gmk_floc *flocp, + struct parent_record **parents); static void record_files (struct nameseq *filenames, const char *pattern, const char *pattern_percent, char *depstr, unsigned int cmds_started, char *commands, @@ -432,7 +436,7 @@ eval_makefile (const char *filename, int flags) /* Add this makefile to the list. */ do_variable_definition (&ebuf.floc, "MAKEFILE_LIST", filename, o_file, - f_append, 0); + f_append, 0, NULL); /* Evaluate the makefile */ @@ -591,6 +595,8 @@ eval (struct ebuffer *ebuf, int set_default) const char *pattern_percent; gmk_floc *fstart; gmk_floc fi; + struct parent_record *parents = NULL; + struct parent_record *new_parents = NULL; #define record_waiting_files() \ do \ @@ -749,7 +755,14 @@ eval (struct ebuffer *ebuf, int set_default) else if (vmod.define_v) v = do_define (p, origin, ebuf); else - v = try_variable_definition (fstart, p, origin, 0); + { + /* duplicate parent_records to avoid wrong link caused by sharing + the same parent_records between variables in the same ifeq + depth */ + dup_parent_records(&new_parents, parents); + + v = try_variable_definition (fstart, p, origin, 0, new_parents); + } assert (v != NULL); @@ -782,7 +795,7 @@ eval (struct ebuffer *ebuf, int set_default) /* Check for conditional state changes. */ { - int i = conditional_line (p, wlen, fstart); + int i = conditional_line (p, wlen, fstart, &parents); if (i != -2) { if (i == -1) @@ -1549,7 +1562,7 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf) definition[idx - 1] = '\0'; v = do_variable_definition (&defstart, name, - definition, origin, var.flavor, 0); + definition, origin, var.flavor, 0, NULL); free (definition); free (n); return (v); @@ -1568,12 +1581,14 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf) 1 if following text should be ignored. */ static int -conditional_line (char *line, int len, const gmk_floc *flocp) +conditional_line (char *line, int len, const gmk_floc *flocp, struct parent_record **parents) { const char *cmdname; enum { c_ifdef, c_ifndef, c_ifeq, c_ifneq, c_else, c_endif } cmdtype; unsigned int i; unsigned int o; + struct variable *current_parent = NULL; + struct parent_record *temp_pr; /* Compare a word, both length and contents. */ #define word1eq(s) (len == CSTRLEN (s) && strneq (s, line, CSTRLEN (s))) @@ -1604,6 +1619,33 @@ conditional_line (char *line, int len, const gmk_floc *flocp) if (!conditionals->if_cmds) EXTRACMD (); + /* Remove temp parent_records belongs to this depth */ + temp_pr = (*parents); + if (temp_pr != NULL) + { + /* Root depth */ + if (temp_pr->depth == conditionals->if_cmds) + { + free_parent_record (temp_pr); + *parents = NULL; + } + else + { + while (temp_pr->next != NULL) + { + /* The next parent_record is not the start node of this depth */ + if (temp_pr->next->depth < conditionals->if_cmds) + temp_pr = temp_pr->next; + else + { + free_parent_record (temp_pr->next); + temp_pr->next = NULL; + break; + } + } + } + } + --conditionals->if_cmds; goto DONE; @@ -1653,7 +1695,7 @@ conditional_line (char *line, int len, const gmk_floc *flocp) /* If it's 'else' or 'endif' or an illegal conditional, fail. */ if (word1eq ("else") || word1eq ("endif") - || conditional_line (line, len, flocp) < 0) + || conditional_line (line, len, flocp, parents) < 0) EXTRATEXT (); else { @@ -1721,12 +1763,32 @@ conditional_line (char *line, int len, const gmk_floc *flocp) conditionals->ignoring[o] = ((v != 0 && *v->value != '\0') == (cmdtype == c_ifndef)); + /* deal with defined parent of variables */ + current_parent = v; + /* if v is defined */ + if ((current_parent != NULL) && (parents != NULL)) + { + /* the first parent */ + if (*parents == NULL) + *parents = alloc_parent_record (current_parent, conditionals->if_cmds); + else + { + /* check the last parent updated */ + temp_pr = (*parents); + while (temp_pr->next != NULL) + temp_pr = temp_pr->next; + + if (current_parent != temp_pr->parent) + temp_pr->next = alloc_parent_record (current_parent, conditionals->if_cmds); + } + } + free (var); } else { /* "ifeq" or "ifneq". */ - char *s1, *s2; + char *s1, *s2, *ps; unsigned int l; char termin = *line == '(' ? ',' : *line; @@ -1764,6 +1826,33 @@ conditional_line (char *line, int len, const gmk_floc *flocp) else *line++ = '\0'; + /* Check if this variable is defined before. */ + /* s1: source string, s2: pointer to variable name, + s3: pointer to closeparen */ + s2 = variable_name_extract(s1, &ps); + if ((s2 != NULL) && (ps != NULL)) + current_parent = lookup_variable (s2, ps - s2); + + /* If this variable is defined, prepare a temp parent_records + for later variable definition. */ + if ((current_parent != NULL) && (parents != NULL)) + { + /* The first parent. */ + if (*parents == NULL) + *parents = alloc_parent_record (current_parent, conditionals->if_cmds); + else + { + /* Check the if the last parent_record is changed. + This means a new parent variable is checked */ + temp_pr = (*parents); + while (temp_pr->next != NULL) + temp_pr = temp_pr->next; + + if (current_parent != temp_pr->parent) + temp_pr->next = alloc_parent_record (current_parent, conditionals->if_cmds); + } + } + s2 = variable_expand (s1); /* We must allocate a new copy of the expanded string because variable_expand re-uses the same buffer. */ @@ -1894,7 +1983,7 @@ record_target_var (struct nameseq *filenames, char *defn, initialize_file_variables (f, 1); current_variable_set_list = f->variables; - v = try_variable_definition (flocp, defn, origin, 1); + v = try_variable_definition (flocp, defn, origin, 1, NULL); if (!v) O (fatal, flocp, _("Malformed target-specific variable definition")); current_variable_set_list = global; @@ -2899,7 +2988,7 @@ construct_include_path (const char **arg_dirs) for (cpp = dirs; *cpp != 0; ++cpp) do_variable_definition (NILF, ".INCLUDE_DIRS", *cpp, - o_default, f_append, 0); + o_default, f_append, 0, NULL); include_directories = dirs; } -- 1.9.1 _______________________________________________ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make