[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 4/6] * read.c: Construct the dependency chain between parent a
From: |
Macpaul Lin |
Subject: |
[PATCH v2 4/6] * read.c: Construct the dependency chain between parent and target variable |
Date: |
Mon, 18 Aug 2014 21:27:13 +0800 |
(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 <address@hidden>
---
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
- [PATCH v2 1/6] * expand.c (variable_name_extract): extract variable name and strip prefix., Macpaul Lin, 2014/08/18
- [PATCH v2 2/6] * variable.h: Add support of struct value_records and parent_records, Macpaul Lin, 2014/08/18
- [PATCH v2 3/6] * variable.c: Add support for constructing value_records and parent_records, Macpaul Lin, 2014/08/18
- [PATCH v2 4/6] * read.c: Construct the dependency chain between parent and target variable,
Macpaul Lin <=
- [PATCH v2 5/6] * load.c: add support of parent_records, Macpaul Lin, 2014/08/18
- [PATCH v2 6/6] * main.c: add --dep parameter for print variable dependency, Macpaul Lin, 2014/08/18
- Re: [PATCH v2 1/6] * expand.c (variable_name_extract): extract variable name and strip prefix., Paul Smith, 2014/08/18