[BACK]Return to parse.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / make

Diff for /src/usr.bin/make/parse.c between version 1.122 and 1.123

version 1.122, 2019/12/21 15:29:25 version 1.123, 2019/12/22 16:53:40
Line 131 
Line 131 
   
 static void ParseLinkSrc(GNode *, GNode *);  static void ParseLinkSrc(GNode *, GNode *);
 static int ParseDoOp(GNode **, unsigned int);  static int ParseDoOp(GNode **, unsigned int);
   static void ParseDoSpecial(GNode *, unsigned int);
 static int ParseAddDep(GNode *, GNode *);  static int ParseAddDep(GNode *, GNode *);
 static void ParseDoSrc(struct growableArray *, struct growableArray *, int,  static void ParseDoSrc(struct growableArray *, struct growableArray *, int,
     const char *, const char *);      const char *, const char *);
Line 282 
Line 283 
  *      Apply the parsed operator to the given target node. Used in a   *      Apply the parsed operator to the given target node. Used in a
  *      Array_Find call by ParseDoDependency once all targets have   *      Array_Find call by ParseDoDependency once all targets have
  *      been found and their operator parsed. If the previous and new   *      been found and their operator parsed. If the previous and new
  *      operators are incompatible, a major error is taken.   *      operators are incompatible, a major error is taken, and the find
    *      stops early
  *   *
  * Side Effects:   * Side Effects:
  *      The type field of the node is altered to reflect any new bits in   *      The node gets the right dependency operator.
  *      the op.   *      Cohorts may be created for double dep.
  *---------------------------------------------------------------------   *---------------------------------------------------------------------
  */   */
 static int  static int
 ParseDoOp(GNode **gnp, unsigned int op)  ParseDoOp(GNode **gnp, unsigned int op)
 {  {
         GNode *gn = *gnp;          GNode *gn = *gnp;
         /*  
          * If the dependency mask of the operator and the node don't match and  
          * the node has actually had an operator applied to it before, and the  
          * operator actually has some dependency information in it, complain.  
          */  
         if (((op & OP_OPMASK) != (gn->type & OP_OPMASK)) &&  
             !OP_NOP(gn->type) && !OP_NOP(op)) {  
                 Parse_Error(PARSE_FATAL,  
                     "Inconsistent dependency operator for target %s\n"  
                     "\t(was %s%s, now %s%s)",  
                     gn->name, gn->name, operator_string(gn->type),  
                     gn->name, operator_string(op));  
                 return 0;  
         }  
   
         if (op == OP_DOUBLEDEP && ((gn->type & OP_OPMASK) == OP_DOUBLEDEP)) {          assert(op == (op & OP_OPMASK));
                 /* If the node was the object of a :: operator, we need to  
                  * create a new instance of it for the children and commands on  
                  * this dependency line. The new instance is placed on the  
                  * 'cohorts' list of the initial one (note the initial one is  
                  * not on its own cohorts list) and the new instance is linked  
                  * to all parents of the initial instance.  */  
                 GNode *cohort;  
                 LstNode ln;  
   
                 cohort = Targ_NewGN(gn->name);          /* if the node didn't already appear on the left hand side (no known
                 /* Duplicate links to parents so graph traversal is simple.           * dependency operator), we don't need to do much. */
                  * Perhaps some type bits should be duplicated?          if (!OP_NOP(gn->type)) {
                  *                  /*
                  * Make the cohort invisible as well to avoid duplicating it                   * If the dependency mask of the operator and the node don't
                  * into other variables. True, parents of this target won't                   * match and the node has actually had an operator applied to
                  * tend to do anything with their local variables, but better                   * it before, and the operator actually has some dependency
                  * safe than sorry.  */                   * information in it, complain.  */
                 for (ln = Lst_First(&gn->parents); ln != NULL; ln = Lst_Adv(ln))                  if (op != (gn->type & OP_OPMASK)) {
                         ParseLinkSrc(Lst_Datum(ln), cohort);                          Parse_Error(PARSE_FATAL,
                 cohort->type = OP_DOUBLEDEP|OP_INVISIBLE;                              "Inconsistent dependency operator for target %s\n"
                 Lst_AtEnd(&gn->cohorts, cohort);                              "\t(was %s%s, now %s%s)",
                               gn->name, gn->name, operator_string(gn->type),
                               gn->name, operator_string(op));
                           return 0;
                   }
   
                 /* Replace the node in the targets list with the new copy */                  if (op == OP_DOUBLEDEP) {
                 *gnp = cohort;                          /* If the node was the object of a :: operator, we need
                 gn = cohort;                           * to create a new instance of it for the children and
                            * commands on this dependency line. The new instance
                            * is placed on the 'cohorts' list of the initial one
                            * (note the initial one is not on its own cohorts
                            * list) and the new instance is linked to all parents
                            * of the initial instance.  */
                           GNode *cohort;
                           LstNode ln;
   
                           cohort = Targ_NewGN(gn->name);
                           /* Duplicate links to parents so graph traversal is
                            * simple.  Perhaps some type bits should be
                            * duplicated?
                            *
                            * Make the cohort invisible as well to avoid
                            * duplicating it into other variables. True, parents
                            * of this target won't tend to do anything with their
                            * local variables, but better safe than sorry.  */
                           for (ln = Lst_First(&gn->parents); ln != NULL;
                               ln = Lst_Adv(ln))
                                   ParseLinkSrc(Lst_Datum(ln), cohort);
                           cohort->type = OP_DOUBLEDEP|OP_INVISIBLE;
                           Lst_AtEnd(&gn->cohorts, cohort);
   
                           /* Replace the node in the targets list with the new
                            * copy */
                           *gnp = cohort;
                           gn = cohort;
                   }
         }          }
         /* We don't want to nuke any previous flags (whatever they were) so we          /* Preserve possible special flags already applied to the operator */
          * just OR the new operator into the old.  */  
         gn->type |= op;          gn->type |= op;
         return 1;          return 1;
 }  }
   
   static void
   ParseDoSpecial(GNode *gn, unsigned int special_op)
   {
           gn->type |= special_op;
   }
   
 /*-  /*-
  *---------------------------------------------------------------------   *---------------------------------------------------------------------
  * ParseAddDep  --   * ParseAddDep  --
Line 404 
Line 421 
         GNode *gn = Targ_FindNodei(src, esrc, TARG_CREATE);          GNode *gn = Targ_FindNodei(src, esrc, TARG_CREATE);
         if ((gn->special & SPECIAL_SOURCE) != 0) {          if ((gn->special & SPECIAL_SOURCE) != 0) {
                 if (gn->special_op) {                  if (gn->special_op) {
                         Array_FindP(targets, ParseDoOp, gn->special_op);                          Array_ForEach(targets, ParseDoSpecial, gn->special_op);
                         return;                          return;
                 } else {                  } else {
                         assert((gn->special & SPECIAL_MASK) == SPECIAL_WAIT);                          assert((gn->special & SPECIAL_MASK) == SPECIAL_WAIT);

Legend:
Removed from v.1.122  
changed lines
  Added in v.1.123