bug-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2 3/6] * variable.c: Add support for constructing value_records


From: Macpaul Lin
Subject: [PATCH v2 3/6] * variable.c: Add support for constructing value_records and parent_records
Date: Mon, 18 Aug 2014 21:27:12 +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.
(dup_parent_records): a function for distinquish variables in the same
conditional line's depth but may have different parents sets.
(print_value_records): a function to dump all value_records, parent_records,
and other parents_records in depths belongs to this variable.

Signed-off-by: Macpaul Lin <address@hidden>
---
Changes for v2:
  - simplify (free_parent_record).
  - simplify (free_variable_record).
  - add (dup_parent_records).
  - add depth support to (dup_parent_records).
  - add (print_value_records).
  - simplify (print_variable).

 variable.c | 258 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 253 insertions(+), 5 deletions(-)

diff --git a/variable.c b/variable.c
index 3f57e7d..5ac2139 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')
@@ -278,12 +279,42 @@ define_variable_in_set (const char *name, unsigned int 
length,
    does not need to be null-terminated. ORIGIN specifies the origin of the
    variable (makefile, command line or environment). */
 
+void
+free_parent_record (struct parent_record *pr)
+{
+  if (pr != NULL)
+    {
+      if (pr->next != NULL)
+         free_parent_record (pr->next);
+      free (pr);
+    }
+}
+
+static void
+free_variable_record (struct value_record *vr)
+{
+  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 +639,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 +1156,92 @@ shell_result (const char *p)
   return result;
 }
 
+/* Given a destination pointer to a parent records, we duplicate the linking
+   list of source parent records to the destination pointer. */
+struct parent_record *
+dup_parent_records (struct parent_record **dst_pr, struct parent_record 
*src_pr)
+{
+  /* Duplicate new parent_record and assign to this variable  */
+  struct parent_record *new_pr = NULL;
+
+  if (src_pr != NULL)
+    {
+       *dst_pr = alloc_parent_record (src_pr->parent, src_pr->depth);
+       (*dst_pr)->next = NULL;
+
+       if (src_pr->next != NULL)
+         {
+           dup_parent_records (&new_pr, src_pr->next);
+           (*dst_pr)->next = new_pr;
+         }
+    }
+
+  return *dst_pr;
+}
+/* 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, unsigned int depth)
+{
+  struct parent_record *pr;
+
+  pr = xmalloc(sizeof(struct parent_record));
+  pr->parent = parent;
+  pr->depth = depth;
+  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 +1483,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 +1711,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,13 +1726,68 @@ 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);
 
   return vp;
 }
 
+/* Print information for variable_record variable VR, prefixing it with 
PREFIX.  */
+
+static void
+print_value_records (struct value_record *src_vr)
+{
+      struct value_record *vr = src_vr;
+      struct parent_record *pr;
+      struct variable *temp_v;
+
+      /* print the first depth of parent  */
+      while (vr != NULL)
+        {
+          printf("value: %s.", vr->value);
+
+          /* Deal with multiple parent */
+          pr = vr->p_records;
+          while (pr != NULL)
+            {
+              putchar (' ');
+              printf("parent: %s = %s;", pr->parent->name, pr->parent->value);
+              pr = pr->next;
+            }
+          /* Deal with multiple value */
+          vr = vr->next;
+          if (vr)
+           putchar (' ');
+        }
+
+      /* print the second depth of parent  */
+      vr = src_vr;
+      while (vr != NULL)
+        {
+          /* Deal with multiple parent */
+          pr = vr->p_records;
+          while (pr != NULL)
+            {
+              /* if this parent has its own parent_records, dump them too.  */
+              temp_v = lookup_variable(pr->parent->name,
+                                       strlen(pr->parent->name));
+              if (temp_v)
+                if (temp_v->v_records)
+                  {
+                    putchar ('\n');
+                    printf ("parent name: %s, ", pr->parent->name);
+                    print_value_records (temp_v->v_records);
+                  }
+              pr = pr->next;
+            }
+          /* Deal with multiple value */
+          vr = vr->next;
+        }
+
+}
+
+
 /* Print information for variable V, prefixing it with PREFIX.  */
 
 static void
@@ -1655,10 +1859,16 @@ print_variable (const void *item, void *arg)
             putchar (*p);
           }
       putchar ('\n');
+
+      /* Dump Dependency of variables.  */
+      if (v->v_records)
+        {
+          print_value_records (v->v_records);
+          putchar ('\n');
+        }
     }
 }
 
-
 static void
 print_auto_variable (const void *item, void *arg)
 {
@@ -1694,6 +1904,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]