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

Diff for /src/usr.bin/awk/run.c between version 1.14 and 1.15

version 1.14, 1999/04/18 17:06:31 version 1.15, 1999/04/20 17:31:30
Line 70 
Line 70 
 Cell    *tmps;          /* free temporary cells for execution */  Cell    *tmps;          /* free temporary cells for execution */
   
 static Cell     truecell        ={ OBOOL, BTRUE, 0, 0, 1.0, NUM };  static Cell     truecell        ={ OBOOL, BTRUE, 0, 0, 1.0, NUM };
 Cell    *true   = &truecell;  Cell    *True   = &truecell;
 static Cell     falsecell       ={ OBOOL, BFALSE, 0, 0, 0.0, NUM };  static Cell     falsecell       ={ OBOOL, BFALSE, 0, 0, 0.0, NUM };
 Cell    *false  = &falsecell;  Cell    *False  = &falsecell;
 static Cell     breakcell       ={ OJUMP, JBREAK, 0, 0, 0.0, NUM };  static Cell     breakcell       ={ OJUMP, JBREAK, 0, 0, 0.0, NUM };
 Cell    *jbreak = &breakcell;  Cell    *jbreak = &breakcell;
 static Cell     contcell        ={ OJUMP, JCONT, 0, 0, 0.0, NUM };  static Cell     contcell        ={ OJUMP, JCONT, 0, 0, 0.0, NUM };
Line 109 
Line 109 
                 /* round up to next multiple of quantum */                  /* round up to next multiple of quantum */
                 if (rminlen)                  if (rminlen)
                         minlen += quantum - rminlen;                          minlen += quantum - rminlen;
                 tbuf = realloc(*pbuf, minlen);                  tbuf = (char *) realloc(*pbuf, minlen);
                 if (tbuf == NULL) {                  if (tbuf == NULL) {
                         if (whatrtn)                          if (whatrtn)
                                 ERROR "out of memory in %s", whatrtn FATAL;                                  ERROR "out of memory in %s", whatrtn FATAL;
Line 136 
Line 136 
         Node *a;          Node *a;
   
         if (u == NULL)          if (u == NULL)
                 return(true);                  return(True);
         for (a = u; ; a = a->nnext) {          for (a = u; ; a = a->nnext) {
                 curnode = a;                  curnode = a;
                 if (isvalue(a)) {                  if (isvalue(a)) {
Line 175 
Line 175 
         if (a[0]) {             /* BEGIN */          if (a[0]) {             /* BEGIN */
                 x = execute(a[0]);                  x = execute(a[0]);
                 if (isexit(x))                  if (isexit(x))
                         return(true);                          return(True);
                 if (isjump(x))                  if (isjump(x))
                         ERROR "illegal break, continue, next or nextfile from BEGIN" FATAL;                          ERROR "illegal break, continue, next or nextfile from BEGIN" FATAL;
                 tempfree(x);                  tempfree(x);
Line 197 
Line 197 
                 tempfree(x);                  tempfree(x);
         }          }
   ex1:    ex1:
         return(true);          return(True);
 }  }
   
 struct Frame {  /* stack frame for awk function calls */  struct Frame {  /* stack frame for awk function calls */
Line 234 
Line 234 
         for (ncall = 0, x = a[1]; x != NULL; x = x->nnext)      /* args in call */          for (ncall = 0, x = a[1]; x != NULL; x = x->nnext)      /* args in call */
                 ncall++;                  ncall++;
         ndef = (int) fcn->fval;                 /* args in defn */          ndef = (int) fcn->fval;                 /* args in defn */
            dprintf( ("calling %s, %d args (%d in defn), fp=%d\n", s, ncall, ndef, fp-frame) );             dprintf( ("calling %s, %d args (%d in defn), fp=%d\n", s, ncall, ndef, (int) (fp-frame)) );
         if (ncall > ndef)          if (ncall > ndef)
                 ERROR "function %s called with %d args, uses only %d",                  ERROR "function %s called with %d args, uses only %d",
                         s, ncall, ndef WARNING;                          s, ncall, ndef WARNING;
         if (ncall + ndef > NARGS)          if (ncall + ndef > NARGS)
                 ERROR "function %s has %d arguments, limit %d", s, ncall+ndef, NARGS FATAL;                  ERROR "function %s has %d arguments, limit %d", s, ncall+ndef, NARGS FATAL;
         for (i = 0, x = a[1]; x != NULL; i++, x = x->nnext) {   /* get call args */          for (i = 0, x = a[1]; x != NULL; i++, x = x->nnext) {   /* get call args */
                    dprintf( ("evaluate args[%d], fp=%d:\n", i, fp-frame) );                     dprintf( ("evaluate args[%d], fp=%d:\n", i, (int) (fp-frame)) );
                 y = execute(x);                  y = execute(x);
                 oargs[i] = y;                  oargs[i] = y;
                    dprintf( ("args[%d]: %s %f <%s>, t=%o\n",                     dprintf( ("args[%d]: %s %f <%s>, t=%o\n",
Line 272 
Line 272 
         fp->nargs = ndef;       /* number defined with (excess are locals) */          fp->nargs = ndef;       /* number defined with (excess are locals) */
         fp->retval = gettemp();          fp->retval = gettemp();
   
            dprintf( ("start exec of %s, fp=%d\n", s, fp-frame) );             dprintf( ("start exec of %s, fp=%d\n", s, (int) (fp-frame)) );
         y = execute((Node *)(fcn->sval));       /* execute body */          y = execute((Node *)(fcn->sval));       /* execute body */
            dprintf( ("finished exec of %s, fp=%d\n", s, fp-frame) );             dprintf( ("finished exec of %s, fp=%d\n", s, (int) (fp-frame)) );
   
         for (i = 0; i < ndef; i++) {          for (i = 0; i < ndef; i++) {
                 Cell *t = fp->args[i];                  Cell *t = fp->args[i];
Line 323 
Line 323 
 Cell *arg(Node **a, int n)      /* nth argument of a function */  Cell *arg(Node **a, int n)      /* nth argument of a function */
 {  {
   
         n = (int) a[0]; /* argument number, counting from 0 */          n = ptoi(a[0]); /* argument number, counting from 0 */
            dprintf( ("arg(%d), fp->nargs=%d\n", n, fp->nargs) );             dprintf( ("arg(%d), fp->nargs=%d\n", n, fp->nargs) );
         if (n+1 > fp->nargs)          if (n+1 > fp->nargs)
                 ERROR "argument #%d of function %s was not supplied",                  ERROR "argument #%d of function %s was not supplied",
Line 382 
Line 382 
         FILE *fp;          FILE *fp;
         char *buf;          char *buf;
         int bufsize = recsize;          int bufsize = recsize;
           int mode;
   
         if ((buf = (char *) malloc(bufsize)) == NULL)          if ((buf = (char *) malloc(bufsize)) == NULL)
                 ERROR "out of memory in getline" FATAL;                  ERROR "out of memory in getline" FATAL;
Line 390 
Line 391 
         r = gettemp();          r = gettemp();
         if (a[1] != NULL) {             /* getline < file */          if (a[1] != NULL) {             /* getline < file */
                 x = execute(a[2]);              /* filename */                  x = execute(a[2]);              /* filename */
                 if ((int) a[1] == '|')          /* input pipe */                  mode = ptoi(a[1]);
                         a[1] = (Node *) LE;     /* arbitrary flag */                  if (mode == '|')                /* input pipe */
                 fp = openfile((int) a[1], getsval(x));                          mode = LE;      /* arbitrary flag */
                   fp = openfile(mode, getsval(x));
                 tempfree(x);                  tempfree(x);
                 if (fp == NULL)                  if (fp == NULL)
                         n = -1;                          n = -1;
Line 442 
Line 444 
         int bufsz = recsize;          int bufsz = recsize;
         int nsub = strlen(*SUBSEP);          int nsub = strlen(*SUBSEP);
   
         if ((buf = malloc(bufsz)) == NULL)          if ((buf = (char *) malloc(bufsz)) == NULL)
                 ERROR "out of memory in array" FATAL;                  ERROR "out of memory in array" FATAL;
   
         x = execute(a[0]);      /* Cell* for symbol table */          x = execute(a[0]);      /* Cell* for symbol table */
Line 482 
Line 484 
   
         x = execute(a[0]);      /* Cell* for symbol table */          x = execute(a[0]);      /* Cell* for symbol table */
         if (!isarr(x))          if (!isarr(x))
                 return true;                  return True;
         if (a[1] == 0) {        /* delete the elements, not the table */          if (a[1] == 0) {        /* delete the elements, not the table */
                 freesymtab(x);                  freesymtab(x);
                 x->tval &= ~STR;                  x->tval &= ~STR;
Line 491 
Line 493 
         } else {          } else {
                 int bufsz = recsize;                  int bufsz = recsize;
                 char *buf;                  char *buf;
                 if ((buf = malloc(bufsz)) == NULL)                  if ((buf = (char *) malloc(bufsz)) == NULL)
                         ERROR "out of memory in adelete" FATAL;                          ERROR "out of memory in adelete" FATAL;
                 buf[0] = 0;                  buf[0] = 0;
                 for (np = a[1]; np; np = np->nnext) {                  for (np = a[1]; np; np = np->nnext) {
Line 508 
Line 510 
                 free(buf);                  free(buf);
         }          }
         tempfree(x);          tempfree(x);
         return true;          return True;
 }  }
   
 Cell *intest(Node **a, int n)   /* a[0] is index (list), a[1] is symtab */  Cell *intest(Node **a, int n)   /* a[0] is index (list), a[1] is symtab */
Line 529 
Line 531 
                 ap->tval |= ARR;                  ap->tval |= ARR;
                 ap->sval = (char *) makesymtab(NSYMTAB);                  ap->sval = (char *) makesymtab(NSYMTAB);
         }          }
         if ((buf = malloc(bufsz)) == NULL) {          if ((buf = (char *) malloc(bufsz)) == NULL) {
                 ERROR "out of memory in intest" FATAL;                  ERROR "out of memory in intest" FATAL;
         }          }
         buf[0] = 0;          buf[0] = 0;
Line 547 
Line 549 
         tempfree(ap);          tempfree(ap);
         free(buf);          free(buf);
         if (k == NULL)          if (k == NULL)
                 return(false);                  return(False);
         else          else
                 return(true);                  return(True);
 }  }
   
   
Line 588 
Line 590 
                 x->fval = start;                  x->fval = start;
                 return x;                  return x;
         } else if ((n == MATCH && i == 1) || (n == NOTMATCH && i == 0))          } else if ((n == MATCH && i == 1) || (n == NOTMATCH && i == 0))
                 return(true);                  return(True);
         else          else
                 return(false);                  return(False);
 }  }
   
   
Line 604 
Line 606 
         tempfree(x);          tempfree(x);
         switch (n) {          switch (n) {
         case BOR:          case BOR:
                 if (i) return(true);                  if (i) return(True);
                 y = execute(a[1]);                  y = execute(a[1]);
                 i = istrue(y);                  i = istrue(y);
                 tempfree(y);                  tempfree(y);
                 if (i) return(true);                  if (i) return(True);
                 else return(false);                  else return(False);
         case AND:          case AND:
                 if ( !i ) return(false);                  if ( !i ) return(False);
                 y = execute(a[1]);                  y = execute(a[1]);
                 i = istrue(y);                  i = istrue(y);
                 tempfree(y);                  tempfree(y);
                 if (i) return(true);                  if (i) return(True);
                 else return(false);                  else return(False);
         case NOT:          case NOT:
                 if (i) return(false);                  if (i) return(False);
                 else return(true);                  else return(True);
         default:        /* can't happen */          default:        /* can't happen */
                 ERROR "unknown boolean operator %d", n FATAL;                  ERROR "unknown boolean operator %d", n FATAL;
         }          }
Line 643 
Line 645 
         tempfree(x);          tempfree(x);
         tempfree(y);          tempfree(y);
         switch (n) {          switch (n) {
         case LT:        if (i<0) return(true);          case LT:        if (i<0) return(True);
                         else return(false);                          else return(False);
         case LE:        if (i<=0) return(true);          case LE:        if (i<=0) return(True);
                         else return(false);                          else return(False);
         case NE:        if (i!=0) return(true);          case NE:        if (i!=0) return(True);
                         else return(false);                          else return(False);
         case EQ:        if (i == 0) return(true);          case EQ:        if (i == 0) return(True);
                         else return(false);                          else return(False);
         case GE:        if (i>=0) return(true);          case GE:        if (i>=0) return(True);
                         else return(false);                          else return(False);
         case GT:        if (i>0) return(true);          case GT:        if (i>0) return(True);
                         else return(false);                          else return(False);
         default:        /* can't happen */          default:        /* can't happen */
                 ERROR "unknown relational operator %d", n FATAL;                  ERROR "unknown relational operator %d", n FATAL;
         }          }
Line 797 
Line 799 
   
         os = s;          os = s;
         p = buf;          p = buf;
         if ((fmt = malloc(fmtsz)) == NULL)          if ((fmt = (char *) malloc(fmtsz)) == NULL)
                 ERROR "out of memory in format()" FATAL;                  ERROR "out of memory in format()" FATAL;
         while (*s) {          while (*s) {
                 adjbuf(&buf, &bufsize, MAXNUMSIZE+1+p-buf, recsize, &p, "format");                  adjbuf(&buf, &bufsize, MAXNUMSIZE+1+p-buf, recsize, &p, "format");
Line 921 
Line 923 
         char *buf;          char *buf;
         int bufsz=3*recsize;          int bufsz=3*recsize;
   
         if ((buf=malloc(bufsz)) == NULL)          if ((buf = (char *) malloc(bufsz)) == NULL)
                 ERROR "out of memory in awksprintf" FATAL;                  ERROR "out of memory in awksprintf" FATAL;
         y = a[0]->nnext;          y = a[0]->nnext;
         x = execute(a[0]);          x = execute(a[0]);
Line 944 
Line 946 
         int len;          int len;
         int bufsz=3*recsize;          int bufsz=3*recsize;
   
         if ((buf=malloc(bufsz)) == NULL)          if ((buf = (char *) malloc(bufsz)) == NULL)
                 ERROR "out of memory in awkprintf" FATAL;                  ERROR "out of memory in awkprintf" FATAL;
         y = a[0]->nnext;          y = a[0]->nnext;
         x = execute(a[0]);          x = execute(a[0]);
Line 957 
Line 959 
                 if (ferror(stdout))                  if (ferror(stdout))
                         ERROR "write error on stdout" FATAL;                          ERROR "write error on stdout" FATAL;
         } else {          } else {
                 fp = redirect((int)a[1], a[2]);                  fp = redirect(ptoi(a[1]), a[2]);
                 /* fputs(buf, fp); */                  /* fputs(buf, fp); */
                 fwrite(buf, len, 1, fp);                  fwrite(buf, len, 1, fp);
                 fflush(fp);                  fflush(fp);
Line 965 
Line 967 
                         ERROR "write error on %s", filename(fp) FATAL;                          ERROR "write error on %s", filename(fp) FATAL;
         }          }
         free(buf);          free(buf);
         return(true);          return(True);
 }  }
   
 Cell *arith(Node **a, int n)    /* a[0] + a[1], etc.  also -a[0] */  Cell *arith(Node **a, int n)    /* a[0] + a[1], etc.  also -a[0] */
Line 1163 
Line 1165 
         Cell *x;          Cell *x;
         int pair;          int pair;
   
         pair = (int) a[3];          pair = ptoi(a[3]);
         if (pairstack[pair] == 0) {          if (pairstack[pair] == 0) {
                 x = execute(a[0]);                  x = execute(a[0]);
                 if (istrue(x))                  if (istrue(x))
Line 1178 
Line 1180 
                 x = execute(a[2]);                  x = execute(a[2]);
                 return(x);                  return(x);
         }          }
         return(false);          return(False);
 }  }
   
 Cell *split(Node **a, int nnn)  /* split(a[0], a[1], a[2]); a[3] is type */  Cell *split(Node **a, int nnn)  /* split(a[0], a[1], a[2]); a[3] is type */
Line 1187 
Line 1189 
         char *s;          char *s;
         int sep;          int sep;
         char *t, temp, num[50], *fs = 0;          char *t, temp, num[50], *fs = 0;
         int n, tempstat;          int n, tempstat, arg3type;
   
         y = execute(a[0]);      /* source string */          y = execute(a[0]);      /* source string */
         s = getsval(y);          s = getsval(y);
           arg3type = ptoi(a[3]);
         if (a[2] == 0)          /* fs string */          if (a[2] == 0)          /* fs string */
                 fs = *FS;                  fs = *FS;
         else if ((int) a[3] == STRING) {        /* split(str,arr,"string") */          else if (arg3type == STRING) {  /* split(str,arr,"string") */
                 x = execute(a[2]);                  x = execute(a[2]);
                 fs = getsval(x);                  fs = getsval(x);
         } else if ((int) a[3] == REGEXPR)          } else if (arg3type == REGEXPR)
                 fs = "(regexpr)";       /* split(str,arr,/regexpr/) */                  fs = "(regexpr)";       /* split(str,arr,/regexpr/) */
         else          else
                 ERROR "illegal type of split" FATAL;                  ERROR "illegal type of split" FATAL;
Line 1209 
Line 1212 
         ap->sval = (char *) makesymtab(NSYMTAB);          ap->sval = (char *) makesymtab(NSYMTAB);
   
         n = 0;          n = 0;
         if ((*s != '\0' && strlen(fs) > 1) || (int) a[3] == REGEXPR) {  /* reg expr */          if ((*s != '\0' && strlen(fs) > 1) || arg3type == REGEXPR) {    /* reg expr */
                 fa *pfa;                  fa *pfa;
                 if ((int) a[3] == REGEXPR) {    /* it's ready already */                  if (arg3type == REGEXPR) {      /* it's ready already */
                         pfa = (fa *) a[2];                          pfa = (fa *) a[2];
                 } else {                  } else {
                         pfa = makedfa(fs, 1);                          pfa = makedfa(fs, 1);
Line 1301 
Line 1304 
         }          }
         tempfree(ap);          tempfree(ap);
         tempfree(y);          tempfree(y);
         if (a[2] != 0 && (int) a[3] == STRING)          if (a[2] != 0 && arg3type == STRING)
                 tempfree(x);                  tempfree(x);
         x = gettemp();          x = gettemp();
         x->tval = NUM;          x->tval = NUM;
Line 1350 
Line 1353 
                 tempfree(x);                  tempfree(x);
                 x = execute(a[1]);                  x = execute(a[1]);
                 if (isbreak(x)) {                  if (isbreak(x)) {
                         x = true;                          x = True;
                         return(x);                          return(x);
                 }                  }
                 if (isnext(x) || isexit(x) || isret(x))                  if (isnext(x) || isexit(x) || isret(x))
Line 1366 
Line 1369 
         for (;;) {          for (;;) {
                 x = execute(a[0]);                  x = execute(a[0]);
                 if (isbreak(x))                  if (isbreak(x))
                         return true;                          return True;
                 if (isnext(x) || isnextfile(x) || isexit(x) || isret(x))                  if (isnext(x) || isnextfile(x) || isexit(x) || isret(x))
                         return(x);                          return(x);
                 tempfree(x);                  tempfree(x);
Line 1391 
Line 1394 
                 }                  }
                 x = execute(a[3]);                  x = execute(a[3]);
                 if (isbreak(x))         /* turn off break */                  if (isbreak(x))         /* turn off break */
                         return true;                          return True;
                 if (isnext(x) || isexit(x) || isret(x))                  if (isnext(x) || isexit(x) || isret(x))
                         return(x);                          return(x);
                 tempfree(x);                  tempfree(x);
Line 1409 
Line 1412 
         vp = execute(a[0]);          vp = execute(a[0]);
         arrayp = execute(a[1]);          arrayp = execute(a[1]);
         if (!isarr(arrayp)) {          if (!isarr(arrayp)) {
                 return true;                  return True;
         }          }
         tp = (Array *) arrayp->sval;          tp = (Array *) arrayp->sval;
         tempfree(arrayp);          tempfree(arrayp);
Line 1420 
Line 1423 
                         x = execute(a[2]);                          x = execute(a[2]);
                         if (isbreak(x)) {                          if (isbreak(x)) {
                                 tempfree(vp);                                  tempfree(vp);
                                 return true;                                  return True;
                         }                          }
                         if (isnext(x) || isexit(x) || isret(x)) {                          if (isnext(x) || isexit(x) || isret(x)) {
                                 tempfree(vp);                                  tempfree(vp);
Line 1429 
Line 1432 
                         tempfree(x);                          tempfree(x);
                 }                  }
         }          }
         return true;          return True;
 }  }
   
 Cell *bltin(Node **a, int n)    /* builtin functions. a[0] is type, a[1] is arg list */  Cell *bltin(Node **a, int n)    /* builtin functions. a[0] is type, a[1] is arg list */
Line 1441 
Line 1444 
         Node *nextarg;          Node *nextarg;
         FILE *fp;          FILE *fp;
   
         t = (int) a[0];          t = ptoi(a[0]);
         x = execute(a[1]);          x = execute(a[1]);
         nextarg = a[1]->nnext;          nextarg = a[1]->nnext;
         switch (t) {          switch (t) {
Line 1532 
Line 1535 
         if (a[1] == 0)  /* a[1] is redirection operator, a[2] is file */          if (a[1] == 0)  /* a[1] is redirection operator, a[2] is file */
                 fp = stdout;                  fp = stdout;
         else          else
                 fp = redirect((int)a[1], a[2]);                  fp = redirect(ptoi(a[1]), a[2]);
         for (x = a[0]; x != NULL; x = x->nnext) {          for (x = a[0]; x != NULL; x = x->nnext) {
                 y = execute(x);                  y = execute(x);
                 fputs(getsval(y), fp);                  fputs(getsval(y), fp);
Line 1546 
Line 1549 
                 fflush(fp);                  fflush(fp);
         if (ferror(fp))          if (ferror(fp))
                 ERROR "write error on %s", filename(fp) FATAL;                  ERROR "write error on %s", filename(fp) FATAL;
         return(true);          return(True);
 }  }
   
 Cell *nullproc(Node **a, int n)  Cell *nullproc(Node **a, int n)
 {  {
         n = 0;          n = n;
         a = 0;          a = a;
         return 0;          return 0;
 }  }
   
Line 1643 
Line 1646 
         Cell *x;          Cell *x;
         int i, stat;          int i, stat;
   
         n = 0;          n = n;
         x = execute(a[0]);          x = execute(a[0]);
         getsval(x);          getsval(x);
         for (i = 0; i < FOPEN_MAX; i++)          for (i = 0; i < FOPEN_MAX; i++)
Line 1662 
Line 1665 
                         files[i].fp = NULL;                          files[i].fp = NULL;
                 }                  }
         tempfree(x);          tempfree(x);
         return(true);          return(True);
 }  }
   
 void closeall(void)  void closeall(void)
Line 1692 
Line 1695 
         fa *pfa;          fa *pfa;
         int bufsz = recsize;          int bufsz = recsize;
   
         if ((buf=malloc(bufsz)) == NULL)          if ((buf = (char *) malloc(bufsz)) == NULL)
                 ERROR "out of memory in sub" FATAL;                  ERROR "out of memory in sub" FATAL;
         x = execute(a[3]);      /* target string */          x = execute(a[3]);      /* target string */
         t = getsval(x);          t = getsval(x);
Line 1704 
Line 1707 
                 tempfree(y);                  tempfree(y);
         }          }
         y = execute(a[2]);      /* replacement string */          y = execute(a[2]);      /* replacement string */
         result = false;          result = False;
         if (pmatch(pfa, t)) {          if (pmatch(pfa, t)) {
                 sptr = t;                  sptr = t;
                 adjbuf(&buf, &bufsz, 1+patbeg-sptr, recsize, 0, "sub");                  adjbuf(&buf, &bufsz, 1+patbeg-sptr, recsize, 0, "sub");
Line 1736 
Line 1739 
                 if (pb > buf + bufsz)                  if (pb > buf + bufsz)
                         ERROR "sub result2 %.30s too big; can't happen", buf FATAL;                          ERROR "sub result2 %.30s too big; can't happen", buf FATAL;
                 setsval(x, buf);        /* BUG: should be able to avoid copy */                  setsval(x, buf);        /* BUG: should be able to avoid copy */
                 result = true;;                  result = True;;
         }          }
         tempfree(x);          tempfree(x);
         tempfree(y);          tempfree(y);
Line 1753 
Line 1756 
         int mflag, tempstat, num;          int mflag, tempstat, num;
         int bufsz = recsize;          int bufsz = recsize;
   
         if ((buf=malloc(bufsz)) == NULL)          if ((buf = (char *) malloc(bufsz)) == NULL)
                 ERROR "out of memory in gsub" FATAL;                  ERROR "out of memory in gsub" FATAL;
         mflag = 0;      /* if mflag == 0, can replace empty string */          mflag = 0;      /* if mflag == 0, can replace empty string */
         num = 0;          num = 0;

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.15