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

Diff for /src/usr.bin/make/for.c between version 1.35 and 1.36

version 1.35, 2007/07/24 18:58:48 version 1.36, 2007/07/24 23:29:49
Line 91 
Line 91 
   
 /* State of a for loop.  */  /* State of a for loop.  */
 struct For_ {  struct For_ {
     char                *text;          /* Unexpanded text              */          char            *text;          /* Unexpanded text              */
     LIST                vars;           /* List of variables            */          LIST            vars;           /* List of variables            */
     LstNode             var;            /* Current var                  */          LstNode         var;            /* Current var                  */
     int                 nvars;          /* Total number of vars         */          int             nvars;          /* Total number of vars         */
     LIST                lst;            /* List of items                */          LIST            lst;            /* List of items                */
     size_t              guess;          /* Estimated expansion size     */          size_t          guess;          /* Estimated expansion size     */
     BUFFER              buf;            /* Accumulating text            */          BUFFER          buf;            /* Accumulating text            */
     unsigned long       lineno;         /* Line number at start of loop */          unsigned long   lineno;         /* Line number at start of loop */
     unsigned long       level;          /* Nesting level                */          unsigned long   level;          /* Nesting level                */
     bool                freeold;          bool            freeold;
 };  };
   
 /* ForExec(value, handle);  /* ForExec(value, handle);
Line 116 
Line 116 
 static unsigned long  static unsigned long
 build_words_list(Lst lst, const char *s)  build_words_list(Lst lst, const char *s)
 {  {
     const char *end, *wrd;          const char *end, *wrd;
     unsigned long n;          unsigned long n;
   
     n = 0;          n = 0;
     end = s;          end = s;
   
     while ((wrd = iterate_words(&end)) != NULL) {          while ((wrd = iterate_words(&end)) != NULL) {
         Lst_AtFront(lst, escape_dupi(wrd, end, "\"'"));                  Lst_AtFront(lst, escape_dupi(wrd, end, "\"'"));
         n++;                  n++;
     }          }
     return n;          return n;
 }  }
   
 For *  For *
 For_Eval(const char *line)  For_Eval(const char *line)
 {  {
     const char  *ptr = line;          const char      *ptr = line;
     const char  *wrd;          const char      *wrd;
     char        *sub;          char    *sub;
     const char  *endVar;          const char      *endVar;
     For         *arg;          For     *arg;
     unsigned long n;          unsigned long n;
   
     while (isspace(*ptr))          while (isspace(*ptr))
         ptr++;                  ptr++;
   
     /* Parse loop.  */          /* Parse loop.  */
   
     arg = emalloc(sizeof(*arg));          arg = emalloc(sizeof(*arg));
     arg->nvars = 0;          arg->nvars = 0;
     Lst_Init(&arg->vars);          Lst_Init(&arg->vars);
   
     for (;;) {          for (;;) {
         /* Grab the variables.  */                  /* Grab the variables.  */
         for (wrd = ptr; *ptr && !isspace(*ptr); ptr++)                  for (wrd = ptr; *ptr && !isspace(*ptr); ptr++)
             continue;                          continue;
         if (ptr - wrd == 0) {                  if (ptr - wrd == 0) {
             Parse_Error(PARSE_FATAL, "Syntax error in for");                          Parse_Error(PARSE_FATAL, "Syntax error in for");
             return 0;                          return 0;
                   }
                   endVar = ptr++;
                   while (isspace(*ptr))
                           ptr++;
                   /* End of variable list ? */
                   if (endVar - wrd == 2 && wrd[0] == 'i' && wrd[1] == 'n')
                           break;
                   Lst_AtEnd(&arg->vars, Var_NewLoopVar(wrd, endVar));
                   arg->nvars++;
         }          }
         endVar = ptr++;          if (arg->nvars == 0) {
         while (isspace(*ptr))                  Parse_Error(PARSE_FATAL, "Missing variable in for");
             ptr++;                  return 0;
         /* End of variable list ? */          }
         if (endVar - wrd == 2 && wrd[0] == 'i' && wrd[1] == 'n')  
             break;  
         Lst_AtEnd(&arg->vars, Var_NewLoopVar(wrd, endVar));  
         arg->nvars++;  
     }  
     if (arg->nvars == 0) {  
         Parse_Error(PARSE_FATAL, "Missing variable in for");  
         return 0;  
     }  
   
     /* Make a list with the remaining words.  */          /* Make a list with the remaining words.  */
     sub = Var_Subst(ptr, NULL, false);          sub = Var_Subst(ptr, NULL, false);
     if (DEBUG(FOR)) {          if (DEBUG(FOR)) {
         LstNode ln;                  LstNode ln;
         (void)fprintf(stderr, "For: Iterator ");                  (void)fprintf(stderr, "For: Iterator ");
         for (ln = Lst_First(&arg->vars); ln != NULL; ln = Lst_Adv(ln))                  for (ln = Lst_First(&arg->vars); ln != NULL; ln = Lst_Adv(ln))
                 (void)fprintf(stderr, "%s ", (char *)Lst_Datum(ln));                          (void)fprintf(stderr, "%s ", (char *)Lst_Datum(ln));
         (void)fprintf(stderr, "List %s\n", sub);                  (void)fprintf(stderr, "List %s\n", sub);
     }          }
   
     Lst_Init(&arg->lst);          Lst_Init(&arg->lst);
     n = build_words_list(&arg->lst, sub);          n = build_words_list(&arg->lst, sub);
     free(sub);          free(sub);
     if (arg->nvars != 1 && n % arg->nvars != 0) {          if (arg->nvars != 1 && n % arg->nvars != 0) {
         Parse_Error(PARSE_FATAL, "Wrong number of items in for loop");                  Parse_Error(PARSE_FATAL, "Wrong number of items in for loop");
         return 0;                  return 0;
     }          }
     arg->lineno = Parse_Getlineno();          arg->lineno = Parse_Getlineno();
     arg->level = 1;          arg->level = 1;
     Buf_Init(&arg->buf, 0);          Buf_Init(&arg->buf, 0);
   
     return arg;          return arg;
 }  }
   
   
 bool  bool
 For_Accumulate(For *arg, const char *line)  For_Accumulate(For *arg, const char *line)
 {  {
     const char      *ptr = line;          const char *ptr = line;
   
     assert(arg->level > 0);          assert(arg->level > 0);
   
     if (*ptr == '.') {          if (*ptr == '.') {
   
         for (ptr++; isspace(*ptr); ptr++)                  for (ptr++; isspace(*ptr); ptr++)
             continue;                          continue;
   
         if (strncmp(ptr, "endfor", 6) == 0 &&                  if (strncmp(ptr, "endfor", 6) == 0 &&
             (isspace(ptr[6]) || !ptr[6])) {                      (isspace(ptr[6]) || !ptr[6])) {
             if (DEBUG(FOR))                          if (DEBUG(FOR))
                 (void)fprintf(stderr, "For: end for %lu\n", arg->level);                                  (void)fprintf(stderr, "For: end for %lu\n",
             /* If matching endfor, don't add line to buffer.  */                                      arg->level);
             if (--arg->level == 0)                          /* If matching endfor, don't add line to buffer.  */
                 return false;                          if (--arg->level == 0)
                                   return false;
                   }
                   else if (strncmp(ptr, "for", 3) == 0 &&
                        isspace(ptr[3])) {
                           arg->level++;
                           if (DEBUG(FOR))
                                   (void)fprintf(stderr, "For: new loop %lu\n",
                                       arg->level);
                   }
         }          }
         else if (strncmp(ptr, "for", 3) == 0 &&          Buf_AddString(&arg->buf, line);
                  isspace(ptr[3])) {          Buf_AddChar(&arg->buf, '\n');
             arg->level++;          return true;
             if (DEBUG(FOR))  
                 (void)fprintf(stderr, "For: new loop %lu\n", arg->level);  
         }  
     }  
     Buf_AddString(&arg->buf, line);  
     Buf_AddChar(&arg->buf, '\n');  
     return true;  
 }  }
   
   
Line 232 
Line 234 
 static void  static void
 ForExec(void *valuep, void *argp)  ForExec(void *valuep, void *argp)
 {  {
     char *value = (char *)valuep;          char *value = (char *)valuep;
     For *arg = (For *)argp;          For *arg = (For *)argp;
     BUFFER buf;          BUFFER buf;
   
     /* Parse_FromString pushes stuff back, so we need to go over vars in          /* Parse_FromString pushes stuff back, so we need to go over vars in
        reverse.  */             reverse.  */
     if (arg->var == NULL) {          if (arg->var == NULL) {
         arg->var = Lst_Last(&arg->vars);                  arg->var = Lst_Last(&arg->vars);
         arg->text = Buf_Retrieve(&arg->buf);                  arg->text = Buf_Retrieve(&arg->buf);
         arg->freeold = false;                  arg->freeold = false;
     }          }
   
     if (DEBUG(FOR))          if (DEBUG(FOR))
         (void)fprintf(stderr, "--- %s = %s\n", (char *)Lst_Datum(arg->var),                  (void)fprintf(stderr, "--- %s = %s\n",
             value);                      (char *)Lst_Datum(arg->var), value);
     Buf_Init(&buf, arg->guess);          Buf_Init(&buf, arg->guess);
     Var_SubstVar(&buf, arg->text, Lst_Datum(arg->var), value);          Var_SubstVar(&buf, arg->text, Lst_Datum(arg->var), value);
     if (arg->freeold)          if (arg->freeold)
         free(arg->text);                  free(arg->text);
     arg->text = Buf_Retrieve(&buf);          arg->text = Buf_Retrieve(&buf);
     arg->freeold = true;          arg->freeold = true;
     arg->var = Lst_Rev(arg->var);          arg->var = Lst_Rev(arg->var);
     if (arg->var == NULL)          if (arg->var == NULL)
         Parse_FromString(arg->text, arg->lineno);                  Parse_FromString(arg->text, arg->lineno);
 }  }
   
   
 void  void
 For_Run(For *arg)  For_Run(For *arg)
 {  {
     arg->text = Buf_Retrieve(&arg->buf);          arg->text = Buf_Retrieve(&arg->buf);
     arg->guess = Buf_Size(&arg->buf) + GUESS_EXPANSION;          arg->guess = Buf_Size(&arg->buf) + GUESS_EXPANSION;
   
     arg->var = NULL;          arg->var = NULL;
     Lst_ForEach(&arg->lst, ForExec, arg);          Lst_ForEach(&arg->lst, ForExec, arg);
     Buf_Destroy(&arg->buf);          Buf_Destroy(&arg->buf);
     Lst_Destroy(&arg->vars, (SimpleProc)Var_DeleteLoopVar);          Lst_Destroy(&arg->vars, (SimpleProc)Var_DeleteLoopVar);
     Lst_Destroy(&arg->lst, (SimpleProc)free);          Lst_Destroy(&arg->lst, (SimpleProc)free);
     free(arg);          free(arg);
 }  }

Legend:
Removed from v.1.35  
changed lines
  Added in v.1.36