[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.23 and 1.24

version 1.23, 2000/11/24 14:29:55 version 1.24, 2001/05/03 13:41:05
Line 1 
Line 1 
   /*      $OpenPackages$ */
 /*      $OpenBSD$       */  /*      $OpenBSD$       */
 /*      $NetBSD: for.c,v 1.4 1996/11/06 17:59:05 christos Exp $ */  /*      $NetBSD: for.c,v 1.4 1996/11/06 17:59:05 christos Exp $ */
   
 /*  /*
  * Copyright (c) 1999 Marc Espie.   * Copyright (c) 1999 Marc Espie.
Line 66 
Line 67 
  *      Functions to handle loops in a makefile.   *      Functions to handle loops in a makefile.
  *   *
  * Interface:   * Interface:
  *      For_Eval        Evaluate the .for in the passed line   *      For_Eval        Evaluate the .for in the passed line.
  *      For_Accumulate  Add lines to an accumulating loop   *      For_Accumulate  Add lines to an accumulating loop
  *      For_Run         Run accumulated loop   *      For_Run         Run accumulated loop
  *   *
  */   */
   
Line 90 
Line 91 
 /*  /*
  * For statements are of the form:   * For statements are of the form:
  *   *
  * .for <variable> in <varlist>   * .for <variable> [variable...] in <varlist>
  * ...   * ...
  * .endfor   * .endfor
  *   *
Line 103 
Line 104 
   
 /* State of a for loop.  */  /* State of a for loop.  */
 struct For_ {  struct For_ {
     char                *text;          /* unexpanded text              */      char                *text;          /* unexpanded text              */
     char                *var;           /* Index name                   */      LIST                vars;           /* list of variables            */
     LIST                lst;            /* List of items                */      LstNode             var;            /* current var                  */
       int                 nvars;          /* total number of vars         */
       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                */
       Boolean             freeold;
 };  };
   
 static void ForExec __P((void *, void *));  static void ForExec(void *, void *);
 static void build_words_list __P((Lst, const char *));  static unsigned long build_words_list(Lst, const char *);
   
 /* Cut a string into words, stuff that into list.  */  /* Cut a string into words, stuff that into list.  */
 static void  static unsigned long
 build_words_list(lst, s)  build_words_list(lst, s)
     Lst lst;      Lst lst;
     const char *s;      const char *s;
 {  {
     const char *end, *wrd;      const char *end, *wrd;
       unsigned long n;
   
       n = 0;
     end = s;      end = s;
   
     while ((wrd = iterate_words(&end)) != NULL)      while ((wrd = iterate_words(&end)) != NULL) {
         Lst_AtFront(lst, escape_dup(wrd, end, "\"'"));          Lst_AtFront(lst, escape_dup(wrd, end, "\"'"));
           n++;
       }
       return n;
 }  }
   
 /*  /*
Line 144 
Line 153 
   
 For *  For *
 For_Eval(line)  For_Eval(line)
     char            *line;    /* Line to parse */      const char      *line;    /* Line to parse */
 {  {
     char        *ptr = line;      const char  *ptr = line;
     char        *wrd;      const char  *wrd;
     char        *sub;      char        *sub;
     char        *endVar;      const char  *endVar;
     For         *arg;      For         *arg;
       unsigned long n;
   
     for (ptr++; *ptr && isspace(*ptr); ptr++)  
         continue;  
     /* If we are not in a for loop quickly determine if the statement is      /* If we are not in a for loop quickly determine if the statement is
      * a for.  */       * a for.  */
     if (ptr[0] != 'f' || ptr[1] != 'o' || ptr[2] != 'r' ||      if (ptr[0] != 'f' || ptr[1] != 'o' || ptr[2] != 'r' ||
Line 166 
Line 174 
   
     /* We found a for loop, and now we are going to parse it.  */      /* We found a for loop, and now we are going to parse it.  */
   
     /* Grab the variable.  */      arg = emalloc(sizeof(*arg));
     for (wrd = ptr; *ptr && !isspace(*ptr); ptr++)      arg->nvars = 0;
         continue;      Lst_Init(&arg->vars);
     if (ptr - wrd == 0) {  
         Parse_Error(PARSE_FATAL, "missing variable in for");      for (;;) {
           /* Grab the variables.  */
           for (wrd = ptr; *ptr && !isspace(*ptr); ptr++)
               continue;
           if (ptr - wrd == 0) {
               Parse_Error(PARSE_FATAL, "Syntax error in for");
               return 0;
           }
           endVar = ptr++;
           while (*ptr && isspace(*ptr))
               ptr++;
           /* finished variable list */
           if (endVar - wrd == 2 && wrd[0] == 'i' && wrd[1] == 'n')
               break;
           Lst_AtEnd(&arg->vars, interval_dup(wrd, endVar));
           arg->nvars++;
       }
       if (arg->nvars == 0) {
           Parse_Error(PARSE_FATAL, "Missing variable in for");
         return 0;          return 0;
     }      }
     endVar = ptr++;  
   
     while (*ptr && isspace(*ptr))  
         ptr++;  
   
     /* Grab the `in'.  */  
     if (ptr[0] != 'i' || ptr[1] != 'n' ||  
         !isspace(ptr[2])) {  
         Parse_Error(PARSE_FATAL, "missing `in' in for");  
         printf("%s\n", ptr);  
         return NULL;  
     }  
     ptr += 3;  
   
     /* .for loop is go, collate what we need.  */  
     arg = emalloc(sizeof(*arg));  
     arg->var = interval_dup(wrd, endVar);  
   
     /* 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)) {
         (void)fprintf(stderr, "For: Iterator %s List %s\n", arg->var, sub);          LstNode ln;
           (void)fprintf(stderr, "For: Iterator ");
           for (ln = Lst_First(&arg->vars); ln != NULL; ln = Lst_Adv(ln))
                   (void)fprintf(stderr, "%s ", (char *)Lst_Datum(ln));
           (void)fprintf(stderr, "List %s\n", sub);
       }
   
     Lst_Init(&arg->lst);      Lst_Init(&arg->lst);
     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) {
           Parse_Error(PARSE_FATAL, "Wrong number of items in for loop");
           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);
Line 206 
Line 224 
     return arg;      return arg;
 }  }
   
   
 /*-  /*-
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  * For_Accumulate --   * For_Accumulate --
Line 222 
Line 240 
  */   */
 Boolean  Boolean
 For_Accumulate(arg, line)  For_Accumulate(arg, line)
     For             *arg;      For             *arg;
     const char      *line;    /* Line to parse */      const char      *line;    /* Line to parse */
 {  {
     const char      *ptr = line;      const char      *ptr = line;
   
Line 269 
Line 287 
 {  {
     char *name = (char *)namep;      char *name = (char *)namep;
     For *arg = (For *)argp;      For *arg = (For *)argp;
       BUFFER buf;
   
       /* Parse_FromString pushes stuff back, so we need to go over vars in
          reverse.  */
       if (arg->var == NULL) {
           arg->var = Lst_Last(&arg->vars);
           arg->text = Buf_Retrieve(&arg->buf);
           arg->freeold = FALSE;
       }
   
     if (DEBUG(FOR))      if (DEBUG(FOR))
         (void)fprintf(stderr, "--- %s = %s\n", arg->var, name);          (void)fprintf(stderr, "--- %s = %s\n", (char *)Lst_Datum(arg->var), name);
     Parse_FromString(Var_SubstVar(arg->text, arg->var, name,      Buf_Init(&buf, arg->guess);
         arg->guess), arg->lineno);      Var_SubstVar(&buf, arg->text, Lst_Datum(arg->var), name);
       if (arg->freeold)
           free(arg->text);
       arg->text = Buf_Retrieve(&buf);
       arg->freeold = TRUE;
       arg->var = Lst_Rev(arg->var);
       if (arg->var == NULL)
           Parse_FromString(arg->text, arg->lineno);
 }  }
   
   
 /*-  /*-
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  * For_Run --   * For_Run --
Line 291 
Line 325 
     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;
     Lst_ForEach(&arg->lst, ForExec, arg);      Lst_ForEach(&arg->lst, ForExec, arg);
     free(arg->var);      Buf_Destroy(&arg->buf);
     free(arg->text);      Lst_Destroy(&arg->vars, (SimpleProc)free);
     Lst_Destroy(&arg->lst, (SimpleProc)free);      Lst_Destroy(&arg->lst, (SimpleProc)free);
     free(arg);      free(arg);
 }  }

Legend:
Removed from v.1.23  
changed lines
  Added in v.1.24