[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 3/6] * variable.c: Add support for constructing value_records and
From: |
Macpaul Lin |
Subject: |
[PATCH 3/6] * variable.c: Add support for constructing value_records and parent_records |
Date: |
Thu, 14 Aug 2014 15:37:36 +0800 |
(define_variable_in_set): assign NULL as initial value of a pointer to
value_record.
(free_parent_record): free all parent_records which were assigned.
(free_variable_record): free all value_records and related parent_records
belongs to a variable.
(free_variable_name_and_value): add free_variable_record to when variable
is going to be destoryed.
(initialize_file_variables): parameters change when do_variable_definition
is called.
(alloc_parent_record): allocate memory for a parent_record.
(do_assign_parent_record): assign a parent_record to its value_record.
(do_assign_value_record): assign a value_record to related variable.
(do_variable_definition): add parent_record related processing to construct
information for a variable.
(assign_variable_definition): add parent_record as a parameter of this wrapper.
(try_variable_definition): add parent_record as a parameter of
do_variable_definition
(print_variable): dump value_record and parent_record for a variable
(print_variable_dep_set): dump dependency of value_record, parent_record of a
variable from a set.
Signed-off-by: Macpaul Lin <address@hidden>
---
variable.c | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 196 insertions(+), 5 deletions(-)
diff --git a/variable.c b/variable.c
index 3f57e7d..6ca5b56 100644
--- a/variable.c
+++ b/variable.c
@@ -254,6 +254,7 @@ define_variable_in_set (const char *name, unsigned int
length,
v->append = 0;
v->private_var = 0;
v->export = v_default;
+ v->v_records = NULL;
v->exportable = 1;
if (*name != '_' && (*name < 'A' || *name > 'Z')
@@ -279,11 +280,47 @@ define_variable_in_set (const char *name, unsigned int
length,
variable (makefile, command line or environment). */
static void
+free_parent_record (struct parent_record *record)
+{
+ struct parent_record *pr;
+
+ pr = record;
+ if (pr != NULL)
+ {
+ if (pr->next != NULL)
+ free_parent_record (pr->next);
+ free (pr);
+ }
+}
+
+static void
+free_variable_record (struct value_record *record)
+{
+ struct value_record *vr;
+
+ vr = record;
+ if (vr != NULL)
+ {
+ if (vr->next != NULL)
+ free_variable_record (vr->next);
+
+ if (vr->p_records != NULL)
+ free_parent_record (vr->p_records);
+
+ free (vr->value);
+ free (vr);
+ }
+}
+
+static void
free_variable_name_and_value (const void *item)
{
struct variable *v = (struct variable *) item;
free (v->name);
free (v->value);
+
+ if (v->v_records)
+ free_variable_record(v->v_records);
}
void
@@ -608,7 +645,7 @@ initialize_file_variables (struct file *file, int reading)
v = do_variable_definition (
&p->variable.fileinfo, p->variable.name,
p->variable.value, p->variable.origin,
- p->variable.flavor, 1);
+ p->variable.flavor, 1, NULL);
}
/* Also mark it as a per-target and copy export status. */
@@ -1125,17 +1162,68 @@ shell_result (const char *p)
return result;
}
+/* Given a variable as a "parent variable" which defines a value for another
+ variable.
+ This function will allocate a struct of parent_record to link these
parents. */
+struct parent_record *
+alloc_parent_record (struct variable *parent)
+{
+ struct parent_record *pr;
+
+ pr = xmalloc(sizeof(struct parent_record));
+ pr->parent = parent;
+ pr->next = NULL;
+
+ return pr;
+}
+/* Given a defined value_record, and a parent_record, link the parents to this
value_record. */
+void
+do_assign_parent_record (struct value_record *vr, struct parent_record
*parents)
+{
+ struct parent_record *pr;
+
+ /* find the last parent_record */
+ pr = vr->p_records;
+
+ if (pr == NULL)
+ vr->p_records = parents;
+ else
+ {
+ while (pr->next != NULL)
+ pr = pr->next;
+ pr->next = parents;
+ }
+}
+
+/* Given a value of variable, return a point to a valuei_record. */
+struct value_record *
+do_assign_value_record (const char *value)
+{
+ struct value_record *vr;
+
+ vr = xmalloc(sizeof(struct value_record));
+ vr->value = xmalloc (strlen (value) + 1);
+ memcpy (vr->value, value, strlen (value));
+ vr->value[strlen (value)] = '\0';
+ vr->p_records = NULL;
+ vr->next = NULL;
+
+ return vr;
+}
+
/* Given a variable, a value, and a flavor, define the variable.
See the try_variable_definition() function for details on the parameters. */
struct variable *
do_variable_definition (const gmk_floc *flocp, const char *varname,
const char *value, enum variable_origin origin,
- enum variable_flavor flavor, int target_var)
+ enum variable_flavor flavor, int target_var,
+ struct parent_record *parents)
{
const char *p;
char *alloc_value = NULL;
struct variable *v;
+ struct value_record *temp_vr, *last_vr;
int append = 0;
int conditional = 0;
@@ -1377,6 +1465,48 @@ do_variable_definition (const gmk_floc *flocp, const
char *varname,
v->append = append;
v->conditional = conditional;
+ /* Check if this value was defined by parent variables (conditional line).
+ If there are parent_records (parents), create value_record (temp_vr) and
+ then link these parent_records with this value_record */
+ if (parents != NULL)
+ {
+ /* check if this vr already exists */
+ temp_vr = v->v_records;
+
+ if (temp_vr == NULL)
+ {
+ temp_vr = do_assign_value_record (value);
+ do_assign_parent_record (temp_vr, parents);
+ v->v_records = temp_vr;
+ }
+ else
+ {
+ /* Deal with multiple parent for the same value */
+ while (temp_vr != NULL)
+ {
+ if (strcmp (temp_vr->value, value))
+ {
+ /* keep the pointer to the second-last */
+ last_vr = temp_vr;
+ temp_vr = temp_vr->next;
+ }
+ else
+ {
+ do_assign_parent_record(temp_vr, parents);
+ break;
+ }
+ }
+
+ /* this means this value is a new one. */
+ if (temp_vr == NULL)
+ {
+ temp_vr = do_assign_value_record (value);
+ do_assign_parent_record (temp_vr, parents);
+ last_vr->next = temp_vr;
+ }
+ }
+ }
+
free (alloc_value);
return v->special ? set_special_var (v) : v;
@@ -1563,7 +1693,8 @@ assign_variable_definition (struct variable *v, const
char *line)
struct variable *
try_variable_definition (const gmk_floc *flocp, const char *line,
- enum variable_origin origin, int target_var)
+ enum variable_origin origin, int target_var,
+ struct parent_record *parents)
{
struct variable v;
struct variable *vp;
@@ -1577,7 +1708,7 @@ try_variable_definition (const gmk_floc *flocp, const
char *line,
return 0;
vp = do_variable_definition (flocp, v.name, v.value,
- origin, v.flavor, target_var);
+ origin, v.flavor, target_var, parents);
free (v.name);
@@ -1636,6 +1767,8 @@ print_variable (const void *item, void *arg)
else
{
char *p;
+ struct value_record *vr;
+ struct parent_record *pr;
printf ("%s %s= ", v->name, v->recursive ? v->append ? "+" : "" : ":");
@@ -1655,10 +1788,30 @@ print_variable (const void *item, void *arg)
putchar (*p);
}
putchar ('\n');
+
+ /* Dump Dependency of variables. */
+ /* Check if the value is just whitespace. */
+ vr = v->v_records;
+ while (vr != NULL)
+ {
+ printf(" value: %s", vr->value);
+
+ /* Deal with multiple parent */
+ pr = vr->p_records;
+ while (pr != NULL)
+ {
+ printf(" parent: %s, value: %s;", pr->parent->name,
+ pr->parent->value);
+ pr = pr->next;
+ }
+ /* Deal with multiple value */
+ vr = vr->next;
+ putchar ('\n');
+ }
+
}
}
-
static void
print_auto_variable (const void *item, void *arg)
{
@@ -1694,6 +1847,44 @@ print_variable_set (struct variable_set *set, const char
*prefix, int pauto)
putc ('\n', stdout);
}
+/* Print all the variables dependency in SET. PREFIX is printed before
+ the actual variable definitions (everything else is comments). */
+
+void
+print_variable_dep_set (struct variable_set *set, const char *prefix, int
pauto)
+{
+ hash_map_arg (&set->table, (pauto ? print_auto_variable : print_variable),
+ (void *)prefix);
+}
+
+/* Print the dependency of variables. */
+
+void
+print_variable_dependency (void)
+{
+ puts (_("\n# Variables\n"));
+
+ print_variable_dep_set (&global_variable_set, "", 0);
+
+ puts (_("\n# Pattern-specific Variable Values"));
+
+ {
+ struct pattern_var *p;
+ int rules = 0;
+
+ for (p = pattern_vars; p != 0; p = p->next)
+ {
+ ++rules;
+ printf ("\n%s :\n", p->target);
+ print_variable (&p->variable, (void *)"# ");
+ }
+ if (rules == 0)
+ puts (_("\n# No pattern-specific variable values."));
+ else
+ printf (_("\n# %u pattern-specific variable values"), rules);
+ }
+}
+
/* Print the data base of variables. */
void
--
1.9.1