[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.10 and 1.11

version 1.10, 1996/09/21 05:03:37 version 1.11, 1996/11/30 21:09:02
Line 1 
Line 1 
 /*      $OpenBSD$       */  /*      $OpenBSD$       */
 /*      $NetBSD: parse.c,v 1.25 1996/09/13 04:22:09 christos Exp $      */  /*      $NetBSD: parse.c,v 1.27 1996/11/06 17:59:20 christos Exp $      */
   
 /*  /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.   * Copyright (c) 1988, 1989, 1990, 1993
  * Copyright (c) 1988, 1989 by Adam de Boor   *      The Regents of the University of California.  All rights reserved.
  * Copyright (c) 1989 by Berkeley Softworks   * Copyright (c) 1989 by Berkeley Softworks
  * All rights reserved.   * All rights reserved.
  *   *
Line 41 
Line 41 
   
 #ifndef lint  #ifndef lint
 #if 0  #if 0
 static char sccsid[] = "@(#)parse.c     5.18 (Berkeley) 2/19/91";  static char sccsid[] = "@(#)parse.c     8.3 (Berkeley) 3/19/94";
 #else  #else
 static char rcsid[] = "$NetBSD: parse.c,v 1.25 1996/09/13 04:22:09 christos Exp $";  static char rcsid[] = "$OpenBSD$";
 #endif  #endif
 #endif /* not lint */  #endif /* not lint */
   
Line 276 
Line 276 
                     end,                      end,
                     cur;                      cur;
     register int    diff;      register int    diff;
   
     start = 0;      start = 0;
     end = (sizeof(parseKeywords)/sizeof(parseKeywords[0])) - 1;      end = (sizeof(parseKeywords)/sizeof(parseKeywords[0])) - 1;
   
Line 399 
Line 399 
     /*      /*
      * 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
      * the operator actually has some dependency information in it, complain.       * the operator actually has some dependency information in it, complain.
      */       */
     if (((op & OP_OPMASK) != (gn->type & OP_OPMASK)) &&      if (((op & OP_OPMASK) != (gn->type & OP_OPMASK)) &&
         !OP_NOP(gn->type) && !OP_NOP(op))          !OP_NOP(gn->type) && !OP_NOP(op))
Line 419 
Line 419 
          */           */
         register GNode  *cohort;          register GNode  *cohort;
         LstNode         ln;          LstNode         ln;
   
         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 443 
Line 443 
     }      }
     /*      /*
      * 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
      * just OR the new operator into the old       * just OR the new operator into the old
      */       */
     gn->type |= op;      gn->type |= op;
   
     return (0);      return (0);
 }  }
   
 /*-  /*-
  *---------------------------------------------------------------------   *---------------------------------------------------------------------
  * ParseAddDep  --   * ParseAddDep  --
  *      Check if the pair of GNodes given needs to be synchronized.   *      Check if the pair of GNodes given needs to be synchronized.
Line 463 
Line 463 
  *   *
  * Side Effects:   * Side Effects:
  *      A dependency can be added between the two nodes.   *      A dependency can be added between the two nodes.
  *   *
  *---------------------------------------------------------------------   *---------------------------------------------------------------------
  */   */
 int  int
Line 738 
Line 738 
   
     curTargs = Lst_Init(FALSE);      curTargs = Lst_Init(FALSE);
     curSrcs = Lst_Init(FALSE);      curSrcs = Lst_Init(FALSE);
   
     do {      do {
         for (cp = line;          for (cp = line;
              *cp && !isspace (*cp) &&               *cp && !isspace (*cp) &&
Line 786 
Line 786 
             }              }
         }          }
         savec = *cp;          savec = *cp;
   
         if (!*cp) {          if (!*cp) {
             /*              /*
              * Ending a dependency line without an operator is a Bozo               * Ending a dependency line without an operator is a Bozo
              * no-no               * no-no
              */               */
             Parse_Error (PARSE_FATAL, "Need an operator");              Parse_Error (PARSE_FATAL, "Need an operator");
             return;              return;
Line 803 
Line 803 
         if (*line == '.' && isupper (line[1])) {          if (*line == '.' && isupper (line[1])) {
             /*              /*
              * See if the target is a special target that must have it               * See if the target is a special target that must have it
              * or its sources handled specially.               * or its sources handled specially.
              */               */
             int keywd = ParseFindKeyword(line);              int keywd = ParseFindKeyword(line);
             if (keywd != -1) {              if (keywd != -1) {
Line 811 
Line 811 
                     Parse_Error(PARSE_FATAL, "Mismatched special targets");                      Parse_Error(PARSE_FATAL, "Mismatched special targets");
                     return;                      return;
                 }                  }
   
                 specType = parseKeywords[keywd].spec;                  specType = parseKeywords[keywd].spec;
                 tOp = parseKeywords[keywd].op;                  tOp = parseKeywords[keywd].op;
   
Line 871 
Line 871 
                     case NotParallel:                      case NotParallel:
                     {                      {
                         extern int  maxJobs;                          extern int  maxJobs;
   
                         maxJobs = 1;                          maxJobs = 1;
                         break;                          break;
                     }                      }
Line 891 
Line 891 
                  * modify.                   * modify.
                  */                   */
                 Lst     path;                  Lst     path;
   
                 specType = ExPath;                  specType = ExPath;
                 path = Suff_GetPath (&line[5]);                  path = Suff_GetPath (&line[5]);
                 if (path == NILLST) {                  if (path == NILLST) {
Line 907 
Line 907 
                 }                  }
             }              }
         }          }
   
         /*          /*
          * Have word in line. Get or create its node and stick it at           * Have word in line. Get or create its node and stick it at
          * the end of the targets list           * the end of the targets list
          */           */
         if ((specType == Not) && (*line != '\0')) {          if ((specType == Not) && (*line != '\0')) {
             if (Dir_HasWildcards(line)) {              if (Dir_HasWildcards(line)) {
Line 921 
Line 921 
                  * Dir module could have added a directory to the path...                   * Dir module could have added a directory to the path...
                  */                   */
                 Lst         emptyPath = Lst_Init(FALSE);                  Lst         emptyPath = Lst_Init(FALSE);
   
                 Dir_Expand(line, emptyPath, curTargs);                  Dir_Expand(line, emptyPath, curTargs);
   
                 Lst_Destroy(emptyPath, Dir_Destroy);                  Lst_Destroy(emptyPath, Dir_Destroy);
             } else {              } else {
                 /*                  /*
Line 932 
Line 932 
                  */                   */
                 (void)Lst_AtEnd(curTargs, (ClientData)line);                  (void)Lst_AtEnd(curTargs, (ClientData)line);
             }              }
   
             while(!Lst_IsEmpty(curTargs)) {              while(!Lst_IsEmpty(curTargs)) {
                 char    *targName = (char *)Lst_DeQueue(curTargs);                  char    *targName = (char *)Lst_DeQueue(curTargs);
   
                 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);
                 }                  }
   
                 (void)Lst_AtEnd (targets, (ClientData)gn);                  (void)Lst_AtEnd (targets, (ClientData)gn);
             }              }
         } 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;
         /*          /*
          * If it is a special type and not .PATH, it's the only target we           * If it is a special type and not .PATH, it's the only target we
Line 955 
Line 955 
          */           */
         if (specType != Not && specType != ExPath) {          if (specType != Not && specType != ExPath) {
             Boolean warn = FALSE;              Boolean warn = FALSE;
   
             while ((*cp != '!') && (*cp != ':') && *cp) {              while ((*cp != '!') && (*cp != ':') && *cp) {
                 if (*cp != ' ' && *cp != '\t') {                  if (*cp != ' ' && *cp != '\t') {
                     warn = TRUE;                      warn = TRUE;
Line 1022 
Line 1022 
     Lst_ForEach (targets, ParseDoOp, (ClientData)&op);      Lst_ForEach (targets, ParseDoOp, (ClientData)&op);
   
     /*      /*
      * Get to the first source       * Get to the first source
      */       */
     while (*cp && isspace (*cp)) {      while (*cp && isspace (*cp)) {
         cp++;          cp++;
Line 1075 
Line 1075 
     } else if ((specType == NotParallel) || (specType == SingleShell)) {      } else if ((specType == NotParallel) || (specType == SingleShell)) {
         *line = '\0';          *line = '\0';
     }      }
   
     /*      /*
      * NOW GO FOR THE SOURCES       * NOW GO FOR THE SOURCES
      */       */
     if ((specType == Suffixes) || (specType == ExPath) ||      if ((specType == Suffixes) || (specType == ExPath) ||
         (specType == Includes) || (specType == Libs) ||          (specType == Includes) || (specType == Libs) ||
Line 1196 
Line 1196 
             line = cp;              line = cp;
         }          }
     }      }
   
     if (mainNode == NILGNODE) {      if (mainNode == NILGNODE) {
         /*          /*
          * If we have yet to decide on a main target to make, in the           * If we have yet to decide on a main target to make, in the
Line 1242 
Line 1242 
     /*      /*
      * Skip to variable name       * Skip to variable name
      */       */
     for (;(*line == ' ') || (*line == '\t'); line++)      for (;(*line == ' ') || (*line == '\t'); line++)
         continue;          continue;
   
     for (; *line != '=' || level != 0; line++)      for (; *line != '=' || level != 0; line++)
Line 1257 
Line 1257 
         case '\t':          case '\t':
             /*              /*
              * there can be as much white space as desired so long as there is               * there can be as much white space as desired so long as there is
              * only one word before the operator               * only one word before the operator
              */               */
             wasSpace = TRUE;              wasSpace = TRUE;
             break;              break;
Line 1271 
Line 1271 
         case ')':          case ')':
             level--;              level--;
             break;              break;
   
         default:          default:
             if (wasSpace && haveName) {              if (wasSpace && haveName) {
                     if (ISEQOPERATOR(*line)) {                      if (ISEQOPERATOR(*line)) {
Line 1302 
Line 1302 
                     return FALSE;                      return FALSE;
             }              }
             else {              else {
                 haveName = TRUE;                  haveName = TRUE;
                 wasSpace = FALSE;                  wasSpace = FALSE;
             }              }
             break;              break;
Line 1341 
Line 1341 
     enum {      enum {
         VAR_SUBST, VAR_APPEND, VAR_SHELL, VAR_NORMAL          VAR_SUBST, VAR_APPEND, VAR_SHELL, VAR_NORMAL
     }               type;       /* Type of assignment */      }               type;       /* Type of assignment */
     char            *opc;       /* ptr to operator character to      char            *opc;       /* ptr to operator character to
                                  * null-terminate the variable name */                                   * null-terminate the variable name */
     /*      /*
      * Avoid clobbered variable warnings by forcing the compiler       * Avoid clobbered variable warnings by forcing the compiler
      * to ``unregister'' variables       * to ``unregister'' variables
      */       */
Line 1549 
Line 1549 
  *---------------------------------------------------------------------   *---------------------------------------------------------------------
  * ParseDoInclude  --   * ParseDoInclude  --
  *      Push to another file.   *      Push to another file.
  *   *
  *      The input is the line minus the #include. A file spec is a string   *      The input is the line minus the #include. A file spec is a string
  *      enclosed in <> or "". The former is looked for only in sysIncPath.   *      enclosed in <> or "". The former is looked for only in sysIncPath.
  *      The latter in . and the directories specified by -I command line   *      The latter in . and the directories specified by -I command line
Line 1641 
Line 1641 
         prefEnd = strrchr (Fname, '/');          prefEnd = strrchr (Fname, '/');
         if (prefEnd != (char *)NULL) {          if (prefEnd != (char *)NULL) {
             char        *newName;              char        *newName;
   
             *prefEnd = '\0';              *prefEnd = '\0';
             if (file[0] == '/')              if (file[0] == '/')
                 newName = estrdup(file);                  newName = estrdup(file);
Line 1731 
Line 1731 
  *---------------------------------------------------------------------   *---------------------------------------------------------------------
  * Parse_FromString  --   * Parse_FromString  --
  *      Start Parsing from the given string   *      Start Parsing from the given string
  *   *
  * Results:   * Results:
  *      None   *      None
  *   *
Line 1754 
Line 1754 
     oldFile->fname = fname;      oldFile->fname = fname;
     oldFile->F = curFILE;      oldFile->F = curFILE;
     oldFile->p = curPTR;      oldFile->p = curPTR;
   
     (void) Lst_AtFront (includes, (ClientData)oldFile);      (void) Lst_AtFront (includes, (ClientData)oldFile);
   
     curFILE = NULL;      curFILE = NULL;
Line 1770 
Line 1770 
  *---------------------------------------------------------------------   *---------------------------------------------------------------------
  * ParseTraditionalInclude  --   * ParseTraditionalInclude  --
  *      Push to another file.   *      Push to another file.
  *   *
  *      The input is the line minus the "include".  The file name is   *      The input is the line minus the "include".  The file name is
  *      the string following the "include".   *      the string following the "include".
  *   *
Line 1833 
Line 1833 
     prefEnd = strrchr (fname, '/');      prefEnd = strrchr (fname, '/');
     if (prefEnd != (char *)NULL) {      if (prefEnd != (char *)NULL) {
         char    *newName;          char    *newName;
   
         *prefEnd = '\0';          *prefEnd = '\0';
         newName = str_concat (fname, file, STR_ADDSLASH);          newName = str_concat (fname, file, STR_ADDSLASH);
         fullname = Dir_FindFile (newName, parseIncPath);          fullname = Dir_FindFile (newName, parseIncPath);
Line 1953 
Line 1953 
 /*-  /*-
  *---------------------------------------------------------------------   *---------------------------------------------------------------------
  * ParseReadc  --   * ParseReadc  --
  *      Read a character from the current file   *      Read a character from the current file
  *   *
  * Results:   * Results:
  *      The character that was read   *      The character that was read
Line 1966 
Line 1966 
 {  {
     if (curFILE)      if (curFILE)
         return fgetc(curFILE);          return fgetc(curFILE);
   
     if (curPTR && *curPTR->ptr)      if (curPTR && *curPTR->ptr)
         return *curPTR->ptr++;          return *curPTR->ptr++;
     return EOF;      return EOF;
Line 1976 
Line 1976 
 /*-  /*-
  *---------------------------------------------------------------------   *---------------------------------------------------------------------
  * ParseUnreadc  --   * ParseUnreadc  --
  *      Put back a character to the current file   *      Put back a character to the current file
  *   *
  * Results:   * Results:
  *      None.   *      None.
Line 2007 
Line 2007 
     int skip;           /* Skip lines that don't start with . */      int skip;           /* Skip lines that don't start with . */
 {  {
     char *line;      char *line;
     int c, lastc = '\0', lineLength;      int c, lastc, lineLength = 0;
     Buffer buf;      Buffer buf;
   
     c = ParseReadc();      buf = Buf_Init(MAKE_BSIZE);
   
     if (skip) {      do {
         /*          Buf_Discard(buf, lineLength);
          * Skip lines until get to one that begins with a          lastc = '\0';
          * special char.  
          */          while (((c = ParseReadc()) != '\n' || lastc == '\\')
         while ((c != '.') && (c != EOF)) {                 && c != EOF) {
             while (((c != '\n') || (lastc == '\\')) && (c != EOF)) {              if (c == '\n') {
                 /*                  Buf_ReplaceLastByte(buf, (Byte)' ');
                  * Advance to next unescaped newline                  lineno++;
                  */  
                 if ((lastc = c) == '\n') {                  while ((c = ParseReadc()) == ' ' || c == '\t');
                     lineno++;  
                 }                  if (c == EOF)
                 c = ParseReadc();                      break;
             }              }
             lineno++;  
               Buf_AddByte(buf, (Byte)c);
             lastc = c;              lastc = c;
             c = ParseReadc ();          }
         }  
     }          if (c == EOF) {
               Parse_Error(PARSE_FATAL, "Unclosed conditional/for loop");
     if (c == EOF) {              Buf_Destroy(buf, TRUE);
         Parse_Error (PARSE_FATAL, "Unclosed conditional/for loop");              return((char *)NULL);
         return ((char *)NULL);          }
     }  
           lineno++;
     /*          Buf_AddByte(buf, (Byte)'\0');
      * Read the entire line into buf          line = (char *)Buf_GetAll(buf, &lineLength);
      */      } while (skip == 1 && line[0] != '.');
     buf = Buf_Init (MAKE_BSIZE);  
     if (c != '\n') {      Buf_Destroy(buf, FALSE);
         lastc = '\0';  
         do {  
             if (lastc != '\0' && lastc != '\n')  
                 Buf_AddByte (buf, (Byte) lastc);  
             if ((lastc = c) == '\n')  
                 lineno++;  
             c = ParseReadc();  
             if (c == '\n' && lastc == '\\')  
                 lastc = '\0';  
         } while (((c != '\n') || (lastc == '\0')) && (c != EOF));  
         if (lastc != '\0' && lastc != '\n')  
             Buf_AddByte (buf, (Byte) lastc);  
     }  
     lineno++;  
   
     Buf_AddByte (buf, (Byte)'\0');  
     line = (char *)Buf_GetAll (buf, &lineLength);  
     Buf_Destroy (buf, FALSE);  
     return line;      return line;
 }  }
   
Line 2127 
Line 2109 
             break;              break;
         }          }
     }      }
   
     if (c != EOF) {      if (c != EOF) {
         lastc = c;          lastc = c;
         buf = Buf_Init(MAKE_BSIZE);          buf = Buf_Init(MAKE_BSIZE);
   
         while (((c = ParseReadc ()) != '\n' || (lastc == '\\')) &&          while (((c = ParseReadc ()) != '\n' || (lastc == '\\')) &&
                (c != EOF))                 (c != EOF))
         {          {
Line 2179 
Line 2161 
                      */                       */
                     ParseUnreadc('\t');                      ParseUnreadc('\t');
                     goto line_read;                      goto line_read;
                 }                  }
                 break;                  break;
             case '=':              case '=':
                 if (!semiNL) {                  if (!semiNL) {
Line 2246 
Line 2228 
              */               */
             Buf_AddByte (buf, (Byte)lastc);              Buf_AddByte (buf, (Byte)lastc);
             lastc = c;              lastc = c;
   
         }          }
     line_read:      line_read:
         lineno++;          lineno++;
   
         if (lastc != '\0') {          if (lastc != '\0') {
             Buf_AddByte (buf, (Byte)lastc);              Buf_AddByte (buf, (Byte)lastc);
         }          }
Line 2266 
Line 2248 
         ep = line;          ep = line;
         while (*ep)          while (*ep)
             ++ep;              ++ep;
         while (ep > line && (ep[-1] == ' ' || ep[-1] == '\t')) {          while (ep > line + 1 && (ep[-1] == ' ' || ep[-1] == '\t')) {
             if (ep > line + 1 && ep[-2] == '\\')              if (ep > line + 1 && ep[-2] == '\\')
                 break;                  break;
             --ep;              --ep;
         }          }
         *ep = 0;          *ep = 0;
   
         if (line[0] == '.') {          if (line[0] == '.') {
             /*              /*
              * The line might be a conditional. Ask the conditional module               * The line might be a conditional. Ask the conditional module
Line 2304 
Line 2286 
                          */                           */
                         line = ParseSkipLine(0);                          line = ParseSkipLine(0);
                         if (line == NULL) {                          if (line == NULL) {
                             Parse_Error (PARSE_FATAL,                              Parse_Error (PARSE_FATAL,
                                      "Unexpected end of file in for loop.\n");                                       "Unexpected end of file in for loop.\n");
                             break;                              break;
                         }                          }
Line 2352 
Line 2334 
         inLine = FALSE;          inLine = FALSE;
     }      }
 }  }
   
   
   
 /*-  /*-
  *---------------------------------------------------------------------   *---------------------------------------------------------------------
  * Parse_File --   * Parse_File --
Line 2413 
Line 2395 
                     goto nextLine;                      goto nextLine;
                 }                  }
             }              }
             if (*line == '#' || *line == '\0') {              if (*line == '#') {
                 /* If we're this far, the line must be a comment.                  /* If we're this far, the line must be a comment. */
                    (Empty lines are ignored as well) */  
                 goto nextLine;                  goto nextLine;
             }              }
   
             if (*line == '\t') {              if (*line == '\t') {
                 /*                  /*
                  * If a line starts with a tab, it can only hope to be                   * If a line starts with a tab, it can only hope to be
Line 2435 
Line 2416 
                         /*                          /*
                          * So long as it's not a blank line and we're actually                           * So long as it's not a blank line and we're actually
                          * in a dependency spec, add the command to the list of                           * in a dependency spec, add the command to the list of
                          * commands of all targets in the dependency spec                           * commands of all targets in the dependency spec
                          */                           */
                         Lst_ForEach (targets, ParseAddCmd, cp);                          Lst_ForEach (targets, ParseAddCmd, cp);
                         Lst_AtEnd(targCmds, (ClientData) line);                          Lst_AtEnd(targCmds, (ClientData) line);
Line 2447 
Line 2428 
                     }                      }
                 }                  }
 #ifdef SYSVINCLUDE  #ifdef SYSVINCLUDE
             } else if (strncmp (line, "include", 7) == 0 &&              } else if (strncmp (line, "include", 7) == 0 &&
                        isspace((unsigned char) line[7]) &&                         isspace((unsigned char) line[7]) &&
                        strchr(line, ':') == NULL) {                         strchr(line, ':') == NULL) {
                 /*                  /*
Line 2473 
Line 2454 
 #ifndef POSIX  #ifndef POSIX
                 Boolean nonSpace = FALSE;                  Boolean nonSpace = FALSE;
 #endif  #endif
   
                 cp = line;                  cp = line;
                 if (isspace((unsigned char) line[0])) {                  if (isspace((unsigned char) line[0])) {
                     while ((*cp != '\0') && isspace((unsigned char) *cp)) {                      while ((*cp != '\0') && isspace((unsigned char) *cp)) {
Line 2489 
Line 2470 
                     }                      }
 #endif  #endif
                 }                  }
   
 #ifndef POSIX  #ifndef POSIX
                 if (*cp == '\0') {                  if (*cp == '\0') {
                     if (inLine) {                      if (inLine) {
Line 2506 
Line 2487 
                     cp = Var_Subst (NULL, line, VAR_CMD, TRUE);                      cp = Var_Subst (NULL, line, VAR_CMD, TRUE);
                     free (line);                      free (line);
                     line = cp;                      line = cp;
   
                     /*                      /*
                      * Need a non-circular list for the target nodes                       * Need a non-circular list for the target nodes
                      */                       */
                     if (targets)                      if (targets)
                         Lst_Destroy(targets, NOFREE);                          Lst_Destroy(targets, NOFREE);
   
                     targets = Lst_Init (FALSE);                      targets = Lst_Init (FALSE);
                     inLine = TRUE;                      inLine = TRUE;
   
                     ParseDoDependency (line);                      ParseDoDependency (line);
 #ifndef POSIX  #ifndef POSIX
                 }                  }
Line 2527 
Line 2508 
             free (line);              free (line);
         }          }
         /*          /*
          * Reached EOF, but it may be just EOF of an include file...           * Reached EOF, but it may be just EOF of an include file...
          */           */
     } while (ParseEOF(1) == CONTINUE);      } while (ParseEOF(1) == CONTINUE);
   
Line 2574 
Line 2555 
     Lst_Destroy(parseIncPath, Dir_Destroy);      Lst_Destroy(parseIncPath, Dir_Destroy);
     Lst_Destroy(includes, NOFREE);      /* Should be empty now */      Lst_Destroy(includes, NOFREE);      /* Should be empty now */
 }  }
   
   
 /*-  /*-
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.11