bug-make
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]