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

Diff for /src/usr.bin/awk/tran.c between version 1.2 and 1.3

version 1.2, 1997/01/20 19:43:24 version 1.3, 1997/08/25 16:17:14
Line 1 
Line 1 
   /*      $OpenBSD$       */
 /****************************************************************  /****************************************************************
 Copyright (C) AT&T and Lucent Technologies 1996  Copyright (C) Lucent Technologies 1997
 All Rights Reserved  All Rights Reserved
   
 Permission to use, copy, modify, and distribute this software and  Permission to use, copy, modify, and distribute this software and
Line 7 
Line 8 
 granted, provided that the above copyright notice appear in all  granted, provided that the above copyright notice appear in all
 copies and that both that the copyright notice and this  copies and that both that the copyright notice and this
 permission notice and warranty disclaimer appear in supporting  permission notice and warranty disclaimer appear in supporting
 documentation, and that the names of AT&T or Lucent Technologies  documentation, and that the name Lucent Technologies or any of
 or any of their entities not be used in advertising or publicity  its entities not be used in advertising or publicity pertaining
 pertaining to distribution of the software without specific,  to distribution of the software without specific, written prior
 written prior permission.  permission.
   
 AT&T AND LUCENT DISCLAIM ALL WARRANTIES WITH REGARD TO THIS  LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
 FITNESS. IN NO EVENT SHALL AT&T OR LUCENT OR ANY OF THEIR  IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
 ENTITIES BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR  IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 USE OR PERFORMANCE OF THIS SOFTWARE.  THIS SOFTWARE.
 ****************************************************************/  ****************************************************************/
   
 #define DEBUG  #define DEBUG
Line 29 
Line 30 
 #include <string.h>  #include <string.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include "awk.h"  #include "awk.h"
 #include "awkgram.h"  #include "ytab.h"
   
 #define FULLTAB 2       /* rehash when table gets this x full */  #define FULLTAB 2       /* rehash when table gets this x full */
 #define GROWTAB 4       /* grow table by this factor */  #define GROWTAB 4       /* grow table by this factor */
Line 51 
Line 52 
 Awkfloat *RSTART;       /* start of re matched with ~; origin 1 (!) */  Awkfloat *RSTART;       /* start of re matched with ~; origin 1 (!) */
 Awkfloat *RLENGTH;      /* length of same */  Awkfloat *RLENGTH;      /* length of same */
   
 Cell    *recloc;        /* location of record */  
 Cell    *nrloc;         /* NR */  Cell    *nrloc;         /* NR */
 Cell    *nfloc;         /* NF */  Cell    *nfloc;         /* NF */
 Cell    *fnrloc;        /* FNR */  Cell    *fnrloc;        /* FNR */
Line 63 
Line 63 
   
 Cell    *nullloc;       /* a guaranteed empty cell */  Cell    *nullloc;       /* a guaranteed empty cell */
 Node    *nullnode;      /* zero&null, converted into a node for comparisons */  Node    *nullnode;      /* zero&null, converted into a node for comparisons */
   Cell    *literal0;
   
 extern Cell *fldtab;  extern Cell **fldtab;
   
 void syminit(void)      /* initialize symbol table with builtin vars */  void syminit(void)      /* initialize symbol table with builtin vars */
 {  {
         setsymtab("0", "0", 0.0, NUM|STR|CON|DONTFREE, symtab);          literal0 = setsymtab("0", "0", 0.0, NUM|STR|CON|DONTFREE, symtab);
         /* this is used for if(x)... tests: */          /* this is used for if(x)... tests: */
         nullloc = setsymtab("$zero&null", "", 0.0, NUM|STR|CON|DONTFREE, symtab);          nullloc = setsymtab("$zero&null", "", 0.0, NUM|STR|CON|DONTFREE, symtab);
         nullnode = valtonode(nullloc, CCON);          nullnode = celltonode(nullloc, CCON);
   
         /* recloc = setsymtab("$0", record, 0.0, REC|STR|DONTFREE, symtab); */  
         /* has been done elsewhere */  
         recloc = &fldtab[0];  
         FS = &setsymtab("FS", " ", 0.0, STR|DONTFREE, symtab)->sval;          FS = &setsymtab("FS", " ", 0.0, STR|DONTFREE, symtab)->sval;
         RS = &setsymtab("RS", "\n", 0.0, STR|DONTFREE, symtab)->sval;          RS = &setsymtab("RS", "\n", 0.0, STR|DONTFREE, symtab)->sval;
         OFS = &setsymtab("OFS", " ", 0.0, STR|DONTFREE, symtab)->sval;          OFS = &setsymtab("OFS", " ", 0.0, STR|DONTFREE, symtab)->sval;
Line 98 
Line 96 
         symtabloc->sval = (char *) symtab;          symtabloc->sval = (char *) symtab;
 }  }
   
 void arginit(int ac, char *av[])        /* set up ARGV and ARGC */  void arginit(int ac, char **av) /* set up ARGV and ARGC */
 {  {
         Cell *cp;          Cell *cp;
         int i;          int i;
         char temp[5];          char temp[50];
   
         ARGC = &setsymtab("ARGC", "", (Awkfloat) ac, NUM, symtab)->fval;          ARGC = &setsymtab("ARGC", "", (Awkfloat) ac, NUM, symtab)->fval;
         cp = setsymtab("ARGV", "", 0.0, ARR, symtab);          cp = setsymtab("ARGV", "", 0.0, ARR, symtab);
         ARGVtab = makesymtab(NSYMTAB);  /* could be (int) ARGC as well */          ARGVtab = makesymtab(NSYMTAB);  /* could be (int) ARGC as well */
         cp->sval = (char *) ARGVtab;          cp->sval = (char *) ARGVtab;
         for (i = 0; i < ac; i++) {          for (i = 0; i < ac; i++) {
                 sprintf((char *)temp, "%d", i);                  sprintf(temp, "%d", i);
                 if (isnumber(*av))                  if (isnumber(*av))
                         setsymtab(temp, *av, atof(*av), STR|NUM, ARGVtab);                          setsymtab(temp, *av, atof(*av), STR|NUM, ARGVtab);
                 else                  else
Line 127 
Line 125 
         ENVtab = makesymtab(NSYMTAB);          ENVtab = makesymtab(NSYMTAB);
         cp->sval = (char *) ENVtab;          cp->sval = (char *) ENVtab;
         for ( ; *envp; envp++) {          for ( ; *envp; envp++) {
                 if ((p = (char *) strchr((char *) *envp, '=')) == NULL)                  if ((p = strchr(*envp, '=')) == NULL)
                         continue;                          continue;
                 *p++ = 0;       /* split into two strings at = */                  *p++ = 0;       /* split into two strings at = */
                 if (isnumber(p))                  if (isnumber(p))
Line 170 
Line 168 
                         if (freeable(cp))                          if (freeable(cp))
                                 xfree(cp->sval);                                  xfree(cp->sval);
                         temp = cp->cnext;       /* avoids freeing then using */                          temp = cp->cnext;       /* avoids freeing then using */
                         free((char *) cp);                          free(cp);
                 }                  }
                 tp->tab[i] = 0;                  tp->tab[i] = 0;
         }          }
         free((char *) (tp->tab));          free(tp->tab);
         free((char *) tp);          free(tp);
 }  }
   
 void freeelem(Cell *ap, char *s)        /* free elem s from ap (i.e., ap["s"] */  void freeelem(Cell *ap, char *s)        /* free elem s from ap (i.e., ap["s"] */
Line 187 
Line 185 
         tp = (Array *) ap->sval;          tp = (Array *) ap->sval;
         h = hash(s, tp->size);          h = hash(s, tp->size);
         for (p = tp->tab[h]; p != NULL; prev = p, p = p->cnext)          for (p = tp->tab[h]; p != NULL; prev = p, p = p->cnext)
                 if (strcmp((char *) s, (char *) p->nval) == 0) {                  if (strcmp(s, p->nval) == 0) {
                         if (prev == NULL)       /* 1st one */                          if (prev == NULL)       /* 1st one */
                                 tp->tab[h] = p->cnext;                                  tp->tab[h] = p->cnext;
                         else                    /* middle somewhere */                          else                    /* middle somewhere */
Line 195 
Line 193 
                         if (freeable(p))                          if (freeable(p))
                                 xfree(p->sval);                                  xfree(p->sval);
                         free(p->nval);                          free(p->nval);
                         free((char *) p);                          free(p);
                         tp->nelem--;                          tp->nelem--;
                         return;                          return;
                 }                  }
Line 207 
Line 205 
         Cell *p;          Cell *p;
   
         if (n != NULL && (p = lookup(n, tp)) != NULL) {          if (n != NULL && (p = lookup(n, tp)) != NULL) {
                 dprintf( ("setsymtab found %p: n=%s s=\"%s\" f=%g t=%o\n",                     dprintf( ("setsymtab found %p: n=%s s=\"%s\" f=%g t=%o\n",
                         p, p->nval, p->sval, p->fval, p->tval) );                          p, p->nval, p->sval, p->fval, p->tval) );
                 return(p);                  return(p);
         }          }
Line 226 
Line 224 
         h = hash(n, tp->size);          h = hash(n, tp->size);
         p->cnext = tp->tab[h];          p->cnext = tp->tab[h];
         tp->tab[h] = p;          tp->tab[h] = p;
         dprintf( ("setsymtab set %p: n=%s s=\"%s\" f=%g t=%o\n",             dprintf( ("setsymtab set %p: n=%s s=\"%s\" f=%g t=%o\n",
                 p, p->nval, p->sval, p->fval, p->tval) );                  p, p->nval, p->sval, p->fval, p->tval) );
         return(p);          return(p);
 }  }
Line 257 
Line 255 
                         np[nh] = cp;                          np[nh] = cp;
                 }                  }
         }          }
         free((char *) (tp->tab));          free(tp->tab);
         tp->tab = np;          tp->tab = np;
         tp->size = nsz;          tp->size = nsz;
 }  }
Line 269 
Line 267 
   
         h = hash(s, tp->size);          h = hash(s, tp->size);
         for (p = tp->tab[h]; p != NULL; prev = p, p = p->cnext)          for (p = tp->tab[h]; p != NULL; prev = p, p = p->cnext)
                 if (strcmp((char *) s, (char *) p->nval) == 0)                  if (strcmp(s, p->nval) == 0)
                         return(p);      /* found it */                          return(p);      /* found it */
         return(NULL);                   /* not found */          return(NULL);                   /* not found */
 }  }
   
 Awkfloat setfval(Cell *vp, Awkfloat f)  /* set float val of a Cell */  Awkfloat setfval(Cell *vp, Awkfloat f)  /* set float val of a Cell */
 {  {
           int fldno;
   
         if ((vp->tval & (NUM | STR)) == 0)          if ((vp->tval & (NUM | STR)) == 0)
                 funnyvar(vp, "assign to");                  funnyvar(vp, "assign to");
         if (vp->tval & FLD) {          if (isfld(vp)) {
                 donerec = 0;    /* mark $0 invalid */                  donerec = 0;    /* mark $0 invalid */
                 if (vp-fldtab > *NF)                  fldno = atoi(vp->nval);
                         newfld(vp-fldtab);                  if (fldno > *NF)
                 dprintf( ("setting field %d to %g\n", vp-fldtab, f) );                          newfld(fldno);
         } else if (vp->tval & REC) {                     dprintf( ("setting field %d to %g\n", fldno, f) );
           } else if (isrec(vp)) {
                 donefld = 0;    /* mark $1... invalid */                  donefld = 0;    /* mark $1... invalid */
                 donerec = 1;                  donerec = 1;
         }          }
         vp->tval &= ~STR;       /* mark string invalid */          vp->tval &= ~STR;       /* mark string invalid */
         vp->tval |= NUM;        /* mark number ok */          vp->tval |= NUM;        /* mark number ok */
         dprintf( ("setfval %p: %s = %g, t=%o\n", vp, vp->nval, f, vp->tval) );             dprintf( ("setfval %p: %s = %g, t=%o\n", vp, vp->nval, f, vp->tval) );
         return vp->fval = f;          return vp->fval = f;
 }  }
   
 void funnyvar(Cell *vp, char *rw)  void funnyvar(Cell *vp, char *rw)
 {  {
         if (vp->tval & ARR)          if (isarr(vp))
                 ERROR "can't %s %s; it's an array name.", rw, vp->nval FATAL;                  ERROR "can't %s %s; it's an array name.", rw, vp->nval FATAL;
         if (vp->tval & FCN)          if (vp->tval & FCN)
                 ERROR "can't %s %s; it's a function.", rw, vp->nval FATAL;                  ERROR "can't %s %s; it's a function.", rw, vp->nval FATAL;
Line 306 
Line 307 
 char *setsval(Cell *vp, char *s)        /* set string val of a Cell */  char *setsval(Cell *vp, char *s)        /* set string val of a Cell */
 {  {
         char *t;          char *t;
           int fldno;
   
              dprintf( ("starting setsval %p: %s = \"%s\", t=%o\n", vp, vp->nval, s, vp->tval) );
         if ((vp->tval & (NUM | STR)) == 0)          if ((vp->tval & (NUM | STR)) == 0)
                 funnyvar(vp, "assign to");                  funnyvar(vp, "assign to");
         if (vp->tval & FLD) {          if (isfld(vp)) {
                 donerec = 0;    /* mark $0 invalid */                  donerec = 0;    /* mark $0 invalid */
                 if (vp-fldtab > *NF)                  fldno = atoi(vp->nval);
                         newfld(vp-fldtab);                  if (fldno > *NF)
                 dprintf( ("setting field %d to %s (%p)\n", vp-fldtab, s, s) );                          newfld(fldno);
         } else if (vp->tval & REC) {                     dprintf( ("setting field %d to %s (%p)\n", fldno, s, s) );
           } else if (isrec(vp)) {
                 donefld = 0;    /* mark $1... invalid */                  donefld = 0;    /* mark $1... invalid */
                 donerec = 1;                  donerec = 1;
         }          }
Line 324 
Line 328 
         if (freeable(vp))          if (freeable(vp))
                 xfree(vp->sval);                  xfree(vp->sval);
         vp->tval &= ~DONTFREE;          vp->tval &= ~DONTFREE;
         dprintf( ("setsval %p: %s = \"%s (%p)\", t=%o\n", vp, vp->nval, t,t, vp->tval) );             dprintf( ("setsval %p: %s = \"%s (%p)\", t=%o\n", vp, vp->nval, t,t, vp->tval) );
         return(vp->sval = t);          return(vp->sval = t);
 }  }
   
Line 332 
Line 336 
 {  {
         if ((vp->tval & (NUM | STR)) == 0)          if ((vp->tval & (NUM | STR)) == 0)
                 funnyvar(vp, "read value of");                  funnyvar(vp, "read value of");
         if ((vp->tval & FLD) && donefld == 0)          if (isfld(vp) && donefld == 0)
                 fldbld();                  fldbld();
         else if ((vp->tval & REC) && donerec == 0)          else if (isrec(vp) && donerec == 0)
                 recbld();                  recbld();
         if (!isnum(vp)) {       /* not a number */          if (!isnum(vp)) {       /* not a number */
                 vp->fval = atof(vp->sval);      /* best guess */                  vp->fval = atof(vp->sval);      /* best guess */
                 if (isnumber(vp->sval) && !(vp->tval&CON))                  if (isnumber(vp->sval) && !(vp->tval&CON))
                         vp->tval |= NUM;        /* make NUM only sparingly */                          vp->tval |= NUM;        /* make NUM only sparingly */
         }          }
         dprintf( ("getfval %p: %s = %g, t=%o\n", vp, vp->nval, vp->fval, vp->tval) );             dprintf( ("getfval %p: %s = %g, t=%o\n", vp, vp->nval, vp->fval, vp->tval) );
         return(vp->fval);          return(vp->fval);
 }  }
   
 char *getsval(Cell *vp) /* get string val of a Cell */  char *getsval(Cell *vp) /* get string val of a Cell */
 {  {
         char s[100];          char s[100];    /* BUG: unchecked */
         double dtemp;          double dtemp;
   
         if ((vp->tval & (NUM | STR)) == 0)          if ((vp->tval & (NUM | STR)) == 0)
                 funnyvar(vp, "read value of");                  funnyvar(vp, "read value of");
         if ((vp->tval & FLD) && donefld == 0)          if (isfld(vp) && donefld == 0)
                 fldbld();                  fldbld();
         else if ((vp->tval & REC) && donerec == 0)          else if (isrec(vp) && donerec == 0)
                 recbld();                  recbld();
         if ((vp->tval & STR) == 0) {          if (isstr(vp) == 0) {
                 if (!(vp->tval&DONTFREE))                  if (freeable(vp))
                         xfree(vp->sval);                          xfree(vp->sval);
                 if (modf(vp->fval, &dtemp) == 0)        /* it's integral */                  if (modf(vp->fval, &dtemp) == 0)        /* it's integral */
                         sprintf((char *)s, "%.20g", vp->fval);                          sprintf(s, "%.30g", vp->fval);
                 else                  else
                         sprintf((char *)s, (char *)*CONVFMT, vp->fval);                          sprintf(s, *CONVFMT, vp->fval);
                 vp->sval = tostring(s);                  vp->sval = tostring(s);
                 vp->tval &= ~DONTFREE;                  vp->tval &= ~DONTFREE;
                 vp->tval |= STR;                  vp->tval |= STR;
         }          }
         dprintf( ("getsval %p: %s = \"%s (%p)\", t=%o\n", vp, vp->nval, vp->sval, vp->sval, vp->tval) );             dprintf( ("getsval %p: %s = \"%s (%p)\", t=%o\n", vp, vp->nval, vp->sval, vp->sval, vp->tval) );
         return(vp->sval);          return(vp->sval);
 }  }
   
Line 375 
Line 379 
 {  {
         char *p;          char *p;
   
         p = (char *) malloc(strlen((char *) s)+1);          p = (char *) malloc(strlen(s)+1);
         if (p == NULL)          if (p == NULL)
                 ERROR "out of space in tostring on %s", s FATAL;                  ERROR "out of space in tostring on %s", s FATAL;
         strcpy((char *) p, (char *) s);          strcpy(p, s);
         return(p);          return(p);
 }  }
   
 char *qstring(char *s, int delim)       /* collect string up to next delim */  char *qstring(char *s, int delim)       /* collect string up to next delim */
 {  {
         int c, n;          int c, n;
           char *buf = 0, *bp;
   
         for (caddreset(gs); (c = *s) != delim; s++) {          if ((buf = (char *) malloc(strlen(s)+3)) == NULL)
                   ERROR "out of space in qstring(%s)", s);
           for (bp = buf; (c = *s) != delim; s++) {
                 if (c == '\n')                  if (c == '\n')
                         ERROR "newline in string %.10s...", gs->cbuf SYNTAX;                          ERROR "newline in string %.10s...", buf SYNTAX;
                 else if (c != '\\')                  else if (c != '\\')
                         cadd(gs, c);                          *bp++ = c;
                 else    /* \something */                  else {  /* \something */
                         switch (c = *++s) {                          switch (c = *++s) {
                         case '\\':      cadd(gs, '\\'); break;                          case '\\':      *bp++ = '\\'; break;
                         case 'n':       cadd(gs, '\n'); break;                          case 'n':       *bp++ = '\n'; break;
                         case 't':       cadd(gs, '\t'); break;                          case 't':       *bp++ = '\t'; break;
                         case 'b':       cadd(gs, '\b'); break;                          case 'b':       *bp++ = '\b'; break;
                         case 'f':       cadd(gs, '\f'); break;                          case 'f':       *bp++ = '\f'; break;
                         case 'r':       cadd(gs, '\r'); break;                          case 'r':       *bp++ = '\r'; break;
                         default:                          default:
                                 if (!isdigit(c)) {                                  if (!isdigit(c)) {
                                         cadd(gs, c);                                          *bp++ = c;
                                         break;                                          break;
                                 }                                  }
                                 n = c - '0';                                  n = c - '0';
Line 410 
Line 417 
                                         if (isdigit(s[1]))                                          if (isdigit(s[1]))
                                                 n = 8 * n + *++s - '0';                                                  n = 8 * n + *++s - '0';
                                 }                                  }
                                 cadd(gs, n);                                  *bp++ = n;
                                 break;                                  break;
                         }                          }
                   }
         }          }
         cadd(gs, 0);          *bp++ = 0;
         return gs->cbuf;          return buf;
 }  }

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3