[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.62 and 1.63

version 1.62, 2001/05/29 12:53:42 version 1.63, 2001/06/12 22:44:21
Line 92 
Line 92 
 #include "extern.h"  #include "extern.h"
 #include "lst.h"  #include "lst.h"
 #include "parsevar.h"  #include "parsevar.h"
   #include "stats.h"
   #include "garray.h"
   
   
   static struct growableArray gsources, gtargets;
   #define SOURCES_SIZE    128
   #define TARGETS_SIZE    32
   
 static LIST     theParseIncPath;/* list of directories for "..." includes */  static LIST     theParseIncPath;/* list of directories for "..." includes */
 static LIST     theSysIncPath;  /* list of directories for <...> includes */  static LIST     theSysIncPath;  /* list of directories for <...> includes */
 Lst sysIncPath = &theSysIncPath;  Lst sysIncPath = &theSysIncPath;
 Lst parseIncPath = &theParseIncPath;  Lst parseIncPath = &theParseIncPath;
   
 static LIST         targets;    /* targets we're working on */  
 #ifdef CLEANUP  #ifdef CLEANUP
 static LIST         targCmds;   /* command lines for targets */  static LIST         targCmds;   /* command lines for targets */
 #endif  #endif
Line 201 
Line 207 
   
 static int ParseFindKeyword(const char *);  static int ParseFindKeyword(const char *);
 static void ParseLinkSrc(GNode *, GNode *);  static void ParseLinkSrc(GNode *, GNode *);
 static int ParseDoOp(void *, void *);  static int ParseDoOp(GNode *, int);
 static int ParseAddDep(void *, void *);  static int ParseAddDep(GNode *, GNode *);
 static void ParseDoSrc(int, const char *, Lst);  static void ParseDoSrc(int, const char *);
 static int ParseFindMain(void *, void *);  static int ParseFindMain(void *, void *);
 static void ParseAddDir(void *, void *);  static void ParseAddDir(void *, void *);
 static void ParseClearPath(void *);  static void ParseClearPath(void *);
Line 295 
Line 301 
  *---------------------------------------------------------------------   *---------------------------------------------------------------------
  */   */
 static int  static int
 ParseDoOp(gnp, opp)  ParseDoOp(gn, op)
     void           *gnp;        /* The node to which the operator is to be      GNode          *gn; /* The node to which the operator is to be
                                  * applied */                                   * applied */
     void           *opp;        /* The operator to apply */      int            op;  /* The operator to apply */
 {  {
     GNode          *gn = (GNode *)gnp;  
     int             op = *(int *)opp;  
     /*      /*
      * If the dependency mask of the operator and the node don't match and       * 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 node has actually had an operator applied to it before, and
Line 322 
Line 326 
          * instance.  */           * instance.  */
         GNode           *cohort;          GNode           *cohort;
         LstNode         ln;          LstNode         ln;
           unsigned int i;
   
         cohort = Targ_NewGN(gn->name);          cohort = Targ_NewGN(gn->name);
         /* Duplicate links to parents so graph traversal is simple. Perhaps          /* Duplicate links to parents so graph traversal is simple. Perhaps
Line 337 
Line 342 
         Lst_AtEnd(&gn->cohorts, cohort);          Lst_AtEnd(&gn->cohorts, cohort);
   
         /* Replace the node in the targets list with the new copy */          /* Replace the node in the targets list with the new copy */
         ln = Lst_Member(&targets, gn);          for (i = 0; i < gtargets.n; i++)
         Lst_Replace(ln, cohort);              if (gtargets.a[i] == gn)
                   break;
           gtargets.a[i] = cohort;
         gn = cohort;          gn = cohort;
     }      }
     /* We don't want to nuke any previous flags (whatever they were) so we      /* We don't want to nuke any previous flags (whatever they were) so we
Line 364 
Line 371 
  *---------------------------------------------------------------------   *---------------------------------------------------------------------
  */   */
 static int  static int
 ParseAddDep(pp, sp)  ParseAddDep(p, s)
     void *pp;      GNode *p;
     void *sp;      GNode *s;
 {  {
     GNode *p = (GNode *)pp;  
     GNode *s = (GNode *)sp;  
   
     if (p->order < s->order) {      if (p->order < s->order) {
         /* XXX: This can cause loops, and loops can cause unmade targets,          /* XXX: This can cause loops, and loops can cause unmade targets,
          * but checking is tedious, and the debugging output can show the           * but checking is tedious, and the debugging output can show the
Line 399 
Line 403 
  *---------------------------------------------------------------------   *---------------------------------------------------------------------
  */   */
 static void  static void
 ParseDoSrc(tOp, src, allsrc)  ParseDoSrc(tOp, src)
     int         tOp;    /* operator (if any) from special targets */      int         tOp;    /* operator (if any) from special targets */
     const char  *src;   /* name of the source to handle */      const char  *src;   /* name of the source to handle */
     Lst         allsrc; /* List of all sources to wait for */  
   
 {  {
     GNode       *gn = NULL;      GNode       *gn = NULL;
Line 412 
Line 415 
         if (keywd != -1) {          if (keywd != -1) {
             int op = parseKeywords[keywd].op;              int op = parseKeywords[keywd].op;
             if (op != 0) {              if (op != 0) {
                 Lst_Find(&targets, ParseDoOp, &op);                  Array_Find(&gtargets, ParseDoOp, op);
                 return;                  return;
             }              }
             if (parseKeywords[keywd].spec == Wait) {              if (parseKeywords[keywd].spec == Wait) {
Line 472 
Line 475 
         if (tOp) {          if (tOp) {
             gn->type |= tOp;              gn->type |= tOp;
         } else {          } else {
             LstNode     ln;              Array_ForEach(&gtargets, ParseLinkSrc, gn);
   
             for (ln = Lst_First(&targets); ln != NULL; ln = Lst_Adv(ln))  
                 ParseLinkSrc((GNode *)Lst_Datum(ln), gn);  
         }          }
         if ((gn->type & OP_OPMASK) == OP_DOUBLEDEP) {          if ((gn->type & OP_OPMASK) == OP_DOUBLEDEP) {
             GNode       *cohort;              GNode       *cohort;
Line 486 
Line 486 
                 if (tOp) {                  if (tOp) {
                     cohort->type |= tOp;                      cohort->type |= tOp;
                 } else {                  } else {
                     LstNode     ln;                      Array_ForEach(&gtargets, ParseLinkSrc, cohort);
   
                     for (ln = Lst_First(&targets); ln != NULL; ln = Lst_Adv(ln))  
                         ParseLinkSrc((GNode *)Lst_Datum(ln), cohort);  
                 }                  }
             }              }
         }          }
Line 497 
Line 494 
     }      }
   
     gn->order = waiting;      gn->order = waiting;
     Lst_AtEnd(allsrc, gn);      Array_AtEnd(&gsources, gn);
     if (waiting) {      if (waiting) {
         Lst_Find(allsrc, ParseAddDep, gn);          Array_Find(&gsources, ParseAddDep, gn);
     }      }
 }  }
   
Line 607 
Line 604 
     LIST            paths;      /* List of search paths to alter when parsing      LIST            paths;      /* List of search paths to alter when parsing
                                  * a list of .PATH targets */                                   * a list of .PATH targets */
     int             tOp;        /* operator from special target */      int             tOp;        /* operator from special target */
     LIST            curTargs;   /* list of target names to be found and added  
                                  * to the targets list */  
     LIST            curSrcs;    /* list of sources in order */  
   
     tOp = 0;      tOp = 0;
   
     specType = Not;      specType = Not;
     waiting = 0;      waiting = 0;
     Lst_Init(&paths);      Lst_Init(&paths);
   
     Lst_Init(&curTargs);      Array_Reset(&gsources);
     Lst_Init(&curSrcs);  
   
     do {      do {
         for (cp = line; *cp && !isspace(*cp) && *cp != '(';)          for (cp = line; *cp && !isspace(*cp) && *cp != '(';)
Line 664 
Line 656 
                 cp++;                  cp++;
             }              }
         if (*cp == '(') {          if (*cp == '(') {
               LIST temp;
               Lst_Init(&temp);
             /* Archives must be handled specially to make sure the OP_ARCHV              /* Archives must be handled specially to make sure the OP_ARCHV
              * flag is set in their 'type' field, for one thing, and because               * flag is set in their 'type' field, for one thing, and because
              * things like "archive(file1.o file2.o file3.o)" are permissible.               * things like "archive(file1.o file2.o file3.o)" are permissible.
Line 672 
Line 666 
              * and places them on the given list, returning true if all               * and places them on the given list, returning true if all
              * went well and false if there was an error in the               * went well and false if there was an error in the
              * specification. On error, line should remain untouched.  */               * specification. On error, line should remain untouched.  */
             if (!Arch_ParseArchive(&line, &targets, NULL)) {              if (!Arch_ParseArchive(&line, &temp, NULL)) {
                 Parse_Error(PARSE_FATAL,                  Parse_Error(PARSE_FATAL,
                              "Error in archive specification: \"%s\"", line);                               "Error in archive specification: \"%s\"", line);
                 return;                  return;
             } else {              } else {
                   AppendList2Array(&temp, &gtargets);
                   Lst_Destroy(&temp, NOFREE);
                 continue;                  continue;
             }              }
         }          }
Line 746 
Line 742 
                     case Interrupt:                      case Interrupt:
                         gn = Targ_FindNode(line, TARG_CREATE);                          gn = Targ_FindNode(line, TARG_CREATE);
                         gn->type |= OP_NOTMAIN;                          gn->type |= OP_NOTMAIN;
                         Lst_AtEnd(&targets, gn);                          Array_AtEnd(&gtargets, gn);
                         break;                          break;
                     case Default:                      case Default:
                         gn = Targ_NewGN(".DEFAULT");                          gn = Targ_NewGN(".DEFAULT");
                         gn->type |= OP_NOTMAIN|OP_TRANSFORM;                          gn->type |= OP_NOTMAIN|OP_TRANSFORM;
                         Lst_AtEnd(&targets, gn);                          Array_AtEnd(&gtargets, gn);
                         DEFAULT = gn;                          DEFAULT = gn;
                         break;                          break;
                     case NotParallel:                      case NotParallel:
Line 806 
Line 802 
                  * Dir module could have added a directory to the path...                   * Dir module could have added a directory to the path...
                  */                   */
                 LIST        emptyPath;                  LIST        emptyPath;
                   LIST        curTargs;   /* list of target names to be found
                                            * and added to the targets list */
   
                 Lst_Init(&emptyPath);                  Lst_Init(&emptyPath);
                   Lst_Init(&curTargs);
                 Dir_Expand(line, &emptyPath, &curTargs);                  Dir_Expand(line, &emptyPath, &curTargs);
                 Lst_Destroy(&emptyPath, Dir_Destroy);                  Lst_Destroy(&emptyPath, Dir_Destroy);
             } else {  
                 /*  
                  * No wildcards, but we want to avoid code duplication,  
                  * so create a list with the word on it.  
                  */  
                 Lst_AtEnd(&curTargs, line);  
             }  
   
             while ((targName = (char *)Lst_DeQueue(&curTargs)) != NULL) {              while ((targName = (char *)Lst_DeQueue(&curTargs)) != NULL) {
                 if (!Suff_IsTransform(targName)) {                      if (!Suff_IsTransform(targName))
                     gn = Targ_FindNode(targName, TARG_CREATE);                      gn = Targ_FindNode(targName, TARG_CREATE);
                 } else {                      else
                     gn = Suff_AddTransform(targName);                      gn = Suff_AddTransform(targName);
   
                       if (gn != NULL)
                           Array_AtEnd(&gtargets, gn);
                 }                  }
                   Lst_Destroy(&curTargs, NOFREE);
               } else {
                   if (!Suff_IsTransform(line))
                       gn = Targ_FindNode(line, TARG_CREATE);
                   else
                       gn = Suff_AddTransform(line);
   
                 if (gn != NULL)                  if (gn != NULL)
                     Lst_AtEnd(&targets, gn);                      Array_AtEnd(&gtargets, gn);
                   /* Don't need the list of target names anymore...  */
             }              }
         } else if (specType == ExPath && *line != '.' && *line != '\0') {          } else if (specType == ExPath && *line != '.' && *line != '\0')
             Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", line);              Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", line);
         }  
   
         *cp = savec;          *cp = savec;
         /*          /*
Line 857 
Line 857 
         line = cp;          line = cp;
     } while (*line != '!' && *line != ':' && *line);      } while (*line != '!' && *line != ':' && *line);
   
     /*      if (!Array_IsEmpty(&gtargets)) {
      * Don't need the list of target names anymore...  
      */  
     Lst_Destroy(&curTargs, NOFREE);  
   
     if (!Lst_IsEmpty(&targets)) {  
         switch (specType) {          switch (specType) {
             default:              default:
                 Parse_Error(PARSE_WARNING, "Special and mundane targets don't mix. Mundane ones ignored");                  Parse_Error(PARSE_WARNING, "Special and mundane targets don't mix. Mundane ones ignored");
Line 897 
Line 892 
   
     cp++;                       /* Advance beyond operator */      cp++;                       /* Advance beyond operator */
   
     Lst_Find(&targets, ParseDoOp, &op);      Array_Find(&gtargets, ParseDoOp, op);
   
     /*      /*
      * Get to the first source       * Get to the first source
Line 1054 
Line 1049 
                 }                  }
   
                 while ((gn = (GNode *)Lst_DeQueue(&sources)) != NULL)                  while ((gn = (GNode *)Lst_DeQueue(&sources)) != NULL)
                     ParseDoSrc(tOp, gn->name, &curSrcs);                      ParseDoSrc(tOp, gn->name);
                 cp = line;                  cp = line;
             } else {              } else {
                 if (*cp) {                  if (*cp) {
Line 1062 
Line 1057 
                     cp += 1;                      cp += 1;
                 }                  }
   
                 ParseDoSrc(tOp, line, &curSrcs);                  ParseDoSrc(tOp, line);
             }              }
             while (*cp && isspace(*cp)) {              while (*cp && isspace(*cp)) {
                 cp++;                  cp++;
Line 1076 
Line 1071 
          * absence of any user input, we want the first target on           * absence of any user input, we want the first target on
          * the first dependency line that is actually a real target           * the first dependency line that is actually a real target
          * (i.e. isn't a .USE or .EXEC rule) to be made.  */           * (i.e. isn't a .USE or .EXEC rule) to be made.  */
         Lst_Find(&targets, ParseFindMain, NULL);          Array_Find(&gtargets, ParseFindMain, NULL);
     }      }
   
     /* Finally, destroy the list of sources.  */      /* Finally, destroy the list of sources.  */
     Lst_Destroy(&curSrcs, NOFREE);  
 }  }
   
 /*-  /*-
Line 1468 
Line 1462 
 static void  static void
 ParseFinishDependency()  ParseFinishDependency()
 {  {
     Lst_Every(&targets, Suff_EndTransform);      Array_Every(&gtargets, Suff_EndTransform);
     Lst_Destroy(&targets, ParseHasCommands);      Array_Every(&gtargets, ParseHasCommands);
       Array_Reset(&gtargets);
 }  }
   
 static void  static void
Line 1480 
Line 1475 
      * commands of all targets in the dependency spec */       * commands of all targets in the dependency spec */
     char *cmd = estrdup(line);      char *cmd = estrdup(line);
   
     Lst_ForEach(&targets, ParseAddCmd, cmd);      Array_ForEach(&gtargets, ParseAddCmd, cmd);
 #ifdef CLEANUP  #ifdef CLEANUP
     Lst_AtEnd(&targCmds, cmd);      Lst_AtEnd(&targCmds, cmd);
 #endif  #endif
Line 1542 
Line 1537 
                         char *end;                          char *end;
   
                         /* Need a new list for the target nodes.  */                          /* Need a new list for the target nodes.  */
                         Lst_Init(&targets);                          Array_Reset(&gtargets);
                         inDependency = true;                          inDependency = true;
   
                         dep = NULL;                          dep = NULL;
Line 1598 
Line 1593 
     mainNode = NULL;      mainNode = NULL;
     Lst_Init(parseIncPath);      Lst_Init(parseIncPath);
     Lst_Init(sysIncPath);      Lst_Init(sysIncPath);
     Lst_Init(&targets);      Array_Init(&gsources, SOURCES_SIZE);
       Array_Init(&gtargets, TARGETS_SIZE);
   
     LowParse_Init();      LowParse_Init();
 #ifdef CLEANUP  #ifdef CLEANUP
     Lst_Init(&targCmds);      Lst_Init(&targCmds);
Line 1610 
Line 1607 
 Parse_End()  Parse_End()
 {  {
     Lst_Destroy(&targCmds, (SimpleProc)free);      Lst_Destroy(&targCmds, (SimpleProc)free);
     Lst_Destroy(&targets, NOFREE);  
     Lst_Destroy(sysIncPath, Dir_Destroy);      Lst_Destroy(sysIncPath, Dir_Destroy);
     Lst_Destroy(parseIncPath, Dir_Destroy);      Lst_Destroy(parseIncPath, Dir_Destroy);
     LowParse_End();      LowParse_End();

Legend:
Removed from v.1.62  
changed lines
  Added in v.1.63