Latest research awk from June 29, 1996
authormillert <millert@openbsd.org>
Mon, 20 Jan 1997 19:43:15 +0000 (19:43 +0000)
committermillert <millert@openbsd.org>
Mon, 20 Jan 1997 19:43:15 +0000 (19:43 +0000)
usr.bin/awk/FIXES
usr.bin/awk/OpenBSD-PATCHES [new file with mode: 0644]
usr.bin/awk/awk.1
usr.bin/awk/awk.h
usr.bin/awk/awklex.l
usr.bin/awk/b.c
usr.bin/awk/lib.c
usr.bin/awk/main.c
usr.bin/awk/run.c
usr.bin/awk/tran.c

index 9ac0b21..9cda6ca 100644 (file)
@@ -458,3 +458,20 @@ May 27, 1996:
 
        thanks to jeffrey friedl for several of these.
 
+May 28, 1996:
+       fixed appalling but apparently unimportant bug in parsing octal
+       numbers in reg exprs.
+
+       explicit hex in reg exprs now limited to 2 chars: \xa, \xaa.
+
+Jun 28, 1996:
+       changed field-splitting to conform to posix definition: fields are
+       split using the value of FS at the time of input; it used to be
+       the value when the field or NF was first referred to, a much less
+       predictable definition.  thanks to arnold robbins for encouragement
+       to do the right thing.
+
+Jun 29, 1996:
+       fixed awful bug in new field splitting; didn't get all the places
+       where input was done.
+
diff --git a/usr.bin/awk/OpenBSD-PATCHES b/usr.bin/awk/OpenBSD-PATCHES
new file mode 100644 (file)
index 0000000..b011fb7
--- /dev/null
@@ -0,0 +1,384 @@
+These are the changes made from Research Awk to allow it to
+build on OpenBSD with flex.  Below is the inof that came
+with the original set of diffs (from 4.4BSD).  ytab.* was
+changed to awkgram.* for make's benefit.
+
+ - todd
+
+From: Vern Paxson <vern@daffy.ee.lbl.gov>
+
+I've ported Research Awk to flex and tested it moderately.  Note that I
+didn't have time to support the nice error-message context stuff (where
+it points out exactly where on a line it thinks an error occurred), as
+the original code made a lot of assumptions regarding the internal
+buffering of a lex scanner that are no longer valid with flex.  Also, the
+sources had a function called "isnumber" which conflicted with a macro by
+the same name in <ctype.h>, so I changed its name to is_a_number.
+
+Let me know if you find more problems.
+
+               Vern
+
+--- /home/millert/tmp/awk/awk.1        Sun Jan 19 18:06:25 1997
++++ awk.1      Sun Jan 19 17:51:39 1997
+@@ -1,3 +1,4 @@
++.\"   $OpenBSD: OpenBSD-PATCHES,v 1.1 1997/01/20 19:43:16 millert Exp $
+ .de EX
+ .nf
+ .ft CW
+@@ -13,7 +14,7 @@
+ .SH NAME
+ awk \- pattern-directed scanning and processing language
+ .SH SYNOPSIS
+-.B awk
++.B awk|nawk
+ [
+ .BI \-F
+ .I fs
+--- /home/millert/tmp/awk/awklex.l     Sun Jan 19 18:06:24 1997
++++ awklex.l   Sun Jan 19 18:00:52 1997
+@@ -29,13 +29,15 @@
+    may not be preserved in other implementations of lex.
+ */
++#ifndef FLEX_SCANNER
+ #undef        input   /* defeat lex */
+ #undef        unput
++#endif /* !FLEX_SCANNER */
+ #include <stdlib.h>
+ #include <string.h>
+ #include "awk.h"
+-#include "ytab.h"
++#include "awkgram.h"
+ extern YYSTYPE        yylval;
+ extern int    infunc;
+@@ -60,6 +62,20 @@
+ char  *s;
+ Gstring       *gs = 0;        /* initialized in main() */
+ int   cflag;
++
++#ifdef FLEX_SCANNER
++static        int     my_input( YY_CHAR *buf, int max_size );
++
++#undef YY_INPUT
++#define YY_INPUT(buf,result,max_size) result = my_input(buf, max_size);
++
++#undef YY_USER_INIT
++#define YY_USER_INIT init_input_source();
++
++#define       FIRST   ((yy_start - 1) / 2)
++#else /* FLEX_SCANNER */
++#define       FIRST   (yybgin - yysvec - 1)
++#endif /* FLEX_SCANNER */
+ %}
+ A     [a-zA-Z_]
+@@ -70,7 +86,7 @@
+ WS    [ \t]
+ %%
+-      switch (yybgin-yysvec-1) {      /* witchcraft */
++      switch (FIRST) {        /* witchcraft */
+       case 0:
+               BEGIN A;
+               break;
+@@ -116,14 +132,20 @@
+ <A>"$"{D}+    { yylval.cp = fieldadr(atoi(yytext+1)); RET(FIELD); }
+ <A>"$NF"      { unputstr("(NF)"); return(INDIRECT); }
+-<A>"$"{A}{B}* { int c, n;
+-                c = input(); unput(c);
+-                if (c == '(' || c == '[' || (infunc && (n=isarg(yytext+1)) >= 0)) {
+-                      unputstr(yytext+1);
+-                      return(INDIRECT);
++<A>"$"{A}{B}* {
++                int c;
++                char *yytext_copy = strdup(yytext);
++                c = input(); unput(c);        /* look for '(' or '[' */
++                if (c == '(' || c == '[' ||
++                    infunc && isarg(yytext_copy+1) >= 0) {
++                        unputstr(yytext_copy+1);
++                        free(yytext_copy);
++                        return(INDIRECT);
+                 } else {
+-                      yylval.cp = setsymtab(yytext+1, "", 0.0, STR|NUM, symtab);
+-                      RET(IVAR);
++                        yylval.cp =
++                              setsymtab(yytext_copy+1,"",0.0,STR|NUM,symtab);
++                        free(yytext_copy);
++                        RET(IVAR);
+                 }
+               }
+ <A>"$"                { RET(INDIRECT); }
+@@ -173,12 +195,15 @@
+ <A>fflush     { yylval.i = FFLUSH; RET(BLTIN); }
+ <A>{A}{B}*    { int n, c;
++                char *yytext_copy = strdup(yytext);
+                 c = input(); unput(c);        /* look for '(' */
+-                if (c != '(' && infunc && (n=isarg(yytext)) >= 0) {
++                if (c != '(' && infunc && (n=isarg(yytext_copy)) >= 0) {
+                       yylval.i = n;
++                      free(yytext_copy);
+                       RET(ARG);
+                 } else {
+-                      yylval.cp = setsymtab(yytext, "", 0.0, STR|NUM, symtab);
++                      yylval.cp = setsymtab(yytext_copy, "", 0.0, STR|NUM, symtab);
++                      free(yytext_copy);
+                       if (c == '(') {
+                               RET(CALL);
+                       } else {
+@@ -237,6 +262,32 @@
+       caddreset(gs);
+ }
++#ifdef FLEX_SCANNER
++static int my_input( YY_CHAR *buf, int max_size )
++{
++      extern uschar *lexprog;
++
++      if ( lexprog ) {                /* awk '...' */
++              int num_chars = strlen( lexprog );
++              if ( num_chars > max_size )
++                      {
++                      num_chars = max_size;
++                      strncpy( buf, lexprog, num_chars );
++                      }
++              else
++                      strcpy( buf, lexprog );
++              lexprog += num_chars;
++              return num_chars;
++
++      } else {                        /* awk -f ... */
++              int c = pgetc();
++              if (c == EOF)
++                      return 0;
++              buf[0] = c;
++              return 1;
++      }
++}
++#else /* FLEX_SCANNER */
+ /* input() and unput() are transcriptions of the standard lex
+    macros for input and output with additions for error message
+    printing.  God help us all if someone changes how lex works.
+@@ -275,7 +326,7 @@
+       if (--ep < ebuf)
+               ep = ebuf + sizeof(ebuf) - 1;
+ }
+-
++#endif /* FLEX_SCANNER */
+ void unputstr(char *s)        /* put a string back on input */
+ {
+@@ -285,6 +336,11 @@
+               unput(s[i]);
+ }
++int lex_input()
++{
++      return input();
++}
++
+ /* growing-string code */
+ const int CBUFLEN = 400;
+@@ -330,3 +386,20 @@
+       free((void *) gs->cbuf);
+       free((void *) gs);
+ }
++
++#ifdef FLEX_SCANNER
++void init_input_source(void)
++{
++      extern int curpfile;
++      extern char *pfile[];
++
++      if (yyin == NULL) {
++              if (pfile[curpfile] == 0)
++                      return;
++              if (strcmp((char *) pfile[curpfile], "-") == 0)
++                      yyin = stdin;
++              else if ((yyin = fopen((char *) pfile[curpfile], "r")) == NULL)
++                      ERROR "can't open file %s", pfile[curpfile] FATAL;
++      }
++}
++#endif
+--- /home/millert/tmp/awk/b.c  Sun Jan 19 18:06:24 1997
++++ b.c        Sun Jan 19 18:00:55 1997
+@@ -31,7 +31,7 @@
+ #include <string.h>
+ #include <stdlib.h>
+ #include "awk.h"
+-#include "ytab.h"
++#include "awkgram.h"
+ #define       HAT     (NCHARS-1)      /* matches ^ in regular expr */
+                               /* NCHARS is 2**n */
+--- /home/millert/tmp/awk/lib.c        Sun Jan 19 18:06:24 1997
++++ lib.c      Sun Jan 19 18:01:45 1997
+@@ -29,7 +29,7 @@
+ #include <errno.h>
+ #include <stdlib.h>
+ #include "awk.h"
+-#include "ytab.h"
++#include "awkgram.h"
+ FILE  *infile = NULL;
+ char  *file   = "";
+@@ -431,7 +431,7 @@
+       if (beenhere++)
+               return;
+-      while ((c = input()) != EOF && c != '\0')
++      while ((c = lex_input()) != EOF && c != '\0')
+               bclass(c);
+       bcheck2(bracecnt, '{', '}');
+       bcheck2(brackcnt, '[', ']');
+@@ -479,6 +479,7 @@
+ void eprint(void)     /* try to print context around error */
+ {
++#if 0
+       char *p, *q;
+       int c;
+       static int been_here = 0;
+@@ -511,6 +512,7 @@
+               }
+       putc('\n', stderr);
+       ep = ebuf;
++#endif
+ }
+ void bclass(int c)
+--- /home/millert/tmp/awk/main.c       Sun Jan 19 18:06:24 1997
++++ main.c     Sun Jan 19 18:00:57 1997
+@@ -27,11 +27,12 @@
+ #define DEBUG
+ #include <stdio.h>
+ #include <ctype.h>
++#include <locale.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <signal.h>
+ #include "awk.h"
+-#include "ytab.h"
++#include "awkgram.h"
+ extern        char    **environ;
+ extern        int     nfields;
+@@ -53,7 +54,12 @@
+       char *fs = NULL, *marg;
+       int temp;
+-      cmdname = argv[0];
++      setlocale(LC_ALL, "");
++
++      if ((cmdname = strrchr(argv[0], '/')) != NULL)
++              cmdname++;
++      else
++              cmdname = argv[0];
+       if (argc == 1) {
+               fprintf(stderr, "Usage: %s [-f programfile | 'program'] [-Ffieldsep] [-v var=value] [-mf n] [-mr n] [files]\n", cmdname);
+               exit(1);
+--- /home/millert/tmp/awk/maketab.c    Sun Jan 19 18:06:24 1997
++++ maketab.c  Sun Jan 19 18:01:08 1997
+@@ -25,14 +25,14 @@
+ /*
+  * this program makes the table to link function names
+  * and type indices that is used by execute() in run.c.
+- * it finds the indices in ytab.h, produced by yacc.
++ * it finds the indices in awkgram.h, produced by yacc.
+  */
+ #include <stdio.h>
+ #include <string.h>
+ #include <stdlib.h>
+ #include "awk.h"
+-#include "ytab.h"
++#include "awkgram.h"
+ struct xx
+ {     int token;
+@@ -120,12 +120,12 @@
+       printf("#include <stdio.h>\n");
+       printf("#include \"awk.h\"\n");
+-      printf("#include \"ytab.h\"\n\n");
++      printf("#include \"awkgram.h\"\n\n");
+       for (i = SIZE; --i >= 0; )
+               names[i] = "";
+-      if ((fp = fopen("ytab.h", "r")) == NULL) {
+-              fprintf(stderr, "maketab can't open ytab.h!\n");
++      if ((fp = fopen("awkgram.h", "r")) == NULL) {
++              fprintf(stderr, "maketab can't open awkgram.h!\n");
+               exit(1);
+       }
+       printf("static char *printname[%d] = {\n", SIZE);
+--- /home/millert/tmp/awk/parse.c      Sun Jan 19 18:06:24 1997
++++ parse.c    Sun Jan 19 18:01:11 1997
+@@ -27,7 +27,7 @@
+ #include <string.h>
+ #include <stdlib.h>
+ #include "awk.h"
+-#include "ytab.h"
++#include "awkgram.h"
+ Node *nodealloc(int n)
+ {
+--- /home/millert/tmp/awk/proto.h      Sun Jan 19 18:06:24 1997
++++ proto.h    Sun Jan 19 17:51:39 1997
+@@ -22,7 +22,6 @@
+ USE OR PERFORMANCE OF THIS SOFTWARE.
+ ****************************************************************/
+-extern        int     yywrap(void);
+ extern        void    setfname(Cell *);
+ extern        int     constnode(Node *);
+ extern        char    *strnode(Node *);
+@@ -31,12 +30,8 @@
+ extern        int     yylex(void);
+ extern        void    startreg(void);
+-extern        int     input(void);
+-extern        void    unput(int);
++extern        int     lex_input(void);
+ extern        void    unputstr(char *);
+-extern        int     yylook(void);
+-extern        int     yyback(int *, int);
+-extern        int     yyinput(void);
+ extern        fa      *makedfa(char *, int);
+ extern        fa      *mkdfa(char *, int);
+@@ -65,6 +60,7 @@
+ extern        void    freefa(fa *);
+ extern        int     pgetc(void);
++extern        void    init_input_source(void);
+ extern        Node    *nodealloc(int);
+ extern        Node    *exptostat(Node *);
+--- /home/millert/tmp/awk/run.c        Sun Jan 19 18:06:24 1997
++++ run.c      Sun Jan 19 18:01:15 1997
+@@ -31,7 +31,7 @@
+ #include <stdlib.h>
+ #include <time.h>
+ #include "awk.h"
+-#include "ytab.h"
++#include "awkgram.h"
+ #define tempfree(x)   if (istemp(x)) tfree(x); else
+--- /home/millert/tmp/awk/tran.c       Sun Jan 19 18:06:24 1997
++++ tran.c     Sun Jan 19 18:01:18 1997
+@@ -29,7 +29,7 @@
+ #include <string.h>
+ #include <stdlib.h>
+ #include "awk.h"
+-#include "ytab.h"
++#include "awkgram.h"
+ #define       FULLTAB 2       /* rehash when table gets this x full */
+ #define       GROWTAB 4       /* grow table by this factor */
index 54b4d3b..c2328ae 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: awk.1,v 1.2 1996/07/06 05:40:03 etheisen Exp $
+.\"    $OpenBSD: awk.1,v 1.3 1997/01/20 19:43:18 millert Exp $
 .de EX
 .nf
 .ft CW
@@ -426,6 +426,7 @@ Variable names with special meanings:
 .TP
 .B CONVFMT
 conversion format used when converting numbers
+(default
 .BR "%.6g" )
 .TP
 .B FS
@@ -484,12 +485,14 @@ Thus local variables may be created by providing excess parameters in
 the function definition.
 .SH EXAMPLES
 .TP
-.B
+.EX
 length($0) > 72
+.EE
 Print lines longer than 72 characters.
 .TP
-.B
+.EX
 { print $2, $1 }
+.EE
 Print first two fields in opposite order.
 .PP
 .EX
@@ -510,8 +513,9 @@ END { print "sum is", s, " average is", s/NR }
 .IP
 Add up first column, print sum and average.
 .TP
-.B
+.EX
 /start/, /stop/
+.EE
 Print all lines between start/stop pairs.
 .PP
 .EX
index 731f6f1..213e433 100644 (file)
@@ -67,6 +67,7 @@ extern int    lineno;         /* line number in awk program */
 extern int     errorflag;      /* 1 if error has occurred */
 extern int     donefld;        /* 1 if record broken into fields */
 extern int     donerec;        /* 1 if record is valid (no fld has changed */
+extern char    inputFS[];      /* FS at time of input, for field splitting */
 
 extern int     dbg;
 
index d7ea235..a179a7d 100644 (file)
@@ -1,4 +1,4 @@
-%Start A strng sc reg comment
+%Start A str sc reg comment
 
 %{
 /****************************************************************
@@ -211,7 +211,7 @@ WS  [ \t]
                        }
                  }
                }
-<A>\"          { BEGIN strng; caddreset(gs); }
+<A>\"          { BEGIN str; caddreset(gs); }
 
 <A>"}"         { if (--bracecnt < 0) ERROR "extra }" SYNTAX; BEGIN sc; RET(';'); }
 <A>"]"         { if (--brackcnt < 0) ERROR "extra ]" SYNTAX; RET(']'); }
@@ -231,28 +231,28 @@ WS        [ \t]
                  RET(REGEXPR); }
 <reg>.         { CADD; }
 
-<strng>\"      { BEGIN A;
+<str>\"                { BEGIN A;
                  cadd(gs, 0); s = tostring(gs->cbuf);
                  cunadd(gs);
                  cadd(gs, ' '); cadd(gs, 0);
                  yylval.cp = setsymtab(gs->cbuf, s, 0.0, CON|STR, symtab);
                  RET(STRING); }
-<strng>\n      { ERROR "newline in string %.10s...", gs->cbuf SYNTAX; lineno++; BEGIN A; }
-<strng>"\\\""  { cadd(gs, '"'); }
-<strng>"\\"n   { cadd(gs, '\n'); }
-<strng>"\\"t   { cadd(gs, '\t'); }
-<strng>"\\"f   { cadd(gs, '\f'); }
-<strng>"\\"r   { cadd(gs, '\r'); }
-<strng>"\\"b   { cadd(gs, '\b'); }
-<strng>"\\"v   { cadd(gs, '\v'); }     /* these ANSIisms may not be known by */
-<strng>"\\"a   { cadd(gs, '\007'); }   /* your compiler. hence 007 for bell */
-<strng>"\\\\"  { cadd(gs, '\\'); }
-<strng>"\\"({O}{O}{O}|{O}{O}|{O}) { int n;
+<str>\n                { ERROR "newline in string %.10s...", gs->cbuf SYNTAX; lineno++; BEGIN A; }
+<str>"\\\""    { cadd(gs, '"'); }
+<str>"\\"n     { cadd(gs, '\n'); }
+<str>"\\"t     { cadd(gs, '\t'); }
+<str>"\\"f     { cadd(gs, '\f'); }
+<str>"\\"r     { cadd(gs, '\r'); }
+<str>"\\"b     { cadd(gs, '\b'); }
+<str>"\\"v     { cadd(gs, '\v'); }     /* these ANSIisms may not be known by */
+<str>"\\"a     { cadd(gs, '\007'); }   /* your compiler. hence 007 for bell */
+<str>"\\\\"    { cadd(gs, '\\'); }
+<str>"\\"({O}{O}{O}|{O}{O}|{O}) { int n;
                  sscanf(yytext+1, "%o", &n); cadd(gs, n); }
-<strng>"\\"x({H}+) { int n;    /* ANSI permits any number! */
+<str>"\\"x({H}+) { int n;      /* ANSI permits any number! */
                  sscanf(yytext+2, "%x", &n); cadd(gs, n); }
-<strng>"\\".   { cadd(gs, yytext[1]); }
-<strng>.       { CADD; }
+<str>"\\".     { cadd(gs, yytext[1]); }
+<str>.         { CADD; }
 
 %%
 
index 3baab2a..9952d94 100644 (file)
@@ -227,11 +227,12 @@ void freetr(Node *p)      /* free parse tree */
 /* to be seen literally;  \056 is not a metacharacter. */
 
 int hexstr(char **pp)  /* find and eval hex string at pp, return new p */
-{
+{                      /* only pick up one 8-bit byte (2 chars) */
        char *p;
        int n = 0;
+       int i;
 
-       for (p = *pp; isxdigit(*p); p++) {
+       for (i = 0, p = *pp; i < 2 && isxdigit(*p); i++, p++) {
                if (isdigit(*p))
                        n = 16 * n + *p - '0';
                else if (*p >= 'a' && *p <= 'f')
@@ -243,7 +244,7 @@ int hexstr(char **pp)       /* find and eval hex string at pp, return new p */
        return n;
 }
 
-#define isoctdigit(c) ((c) >= '0' && (c) <= '8')       /* multiple use of arg */
+#define isoctdigit(c) ((c) >= '0' && (c) <= '7')       /* multiple use of arg */
 
 int quoted(char **pp)  /* pick up next thing after a \\ */
                        /* and increment *pp */
index 6f72be9..613e8f0 100644 (file)
@@ -38,6 +38,7 @@ char  *recdata;
 char   *record;
 char   *fields;
 Cell   *fldtab;
+char   inputFS[100];   /* BUG: unchecked */
 
 #define        MAXFLD  200
 int    nfields = MAXFLD;       /* can be set from commandline in main */
@@ -158,6 +159,7 @@ int readrec(char *buf, int bufsize, FILE *inf)      /* read one record into buf */
        char *rr;
        int nrr;
 
+       strcpy(inputFS, *FS);   /* for subsequent field splitting */
        if ((sep = **RS) == 0) {
                sep = '\n';
                while ((c=getc(inf)) == '\n' && c != EOF)       /* skip leading \n's */
@@ -228,9 +230,9 @@ void fldbld(void)   /* create fields from current record */
        r = recloc->sval;
        fr = fields;
        i = 0;  /* number of fields accumulated here */
-       if (strlen(*FS) > 1) {  /* it's a regular expression */
-               i = refldbld(r, *FS);
-       } else if ((sep = **FS) == ' ') {       /* default whitespace */
+       if (strlen(inputFS) > 1) {      /* it's a regular expression */
+               i = refldbld(r, inputFS);
+       } else if ((sep = *inputFS) == ' ') {   /* default whitespace */
                for (i = 0; ; ) {
                        while (*r == ' ' || *r == '\t' || *r == '\n')
                                r++;
@@ -249,7 +251,7 @@ void fldbld(void)   /* create fields from current record */
                        *fr++ = 0;
                }
                *fr = 0;
-       } else if ((sep = **FS) == 0) {         /* new: FS="" => 1 char/field */
+       } else if ((sep = *inputFS) == 0) {             /* new: FS="" => 1 char/field */
                for (i = 0; *r != 0; r++) {
                        char buf[2];
                        i++;
@@ -381,10 +383,10 @@ void recbld(void) /* create $0 from $1..$NF if necessary */
        if (r > rec + recsize - 1)
                ERROR "built giant record `%.30s...'; try -mr n", record FATAL;
        *r = '\0';
-       dprintf( ("in recbld FS=%o, recloc=%p\n", **FS, recloc) );
+       dprintf( ("in recbld inputFS=%s, recloc=%p\n", inputFS, recloc) );
        recloc->tval = REC | STR | DONTFREE;
        recloc->sval = record = rec;
-       dprintf( ("in recbld FS=%o, recloc=%p\n", **FS, recloc) );
+       dprintf( ("in recbld inputFS=%s, recloc=%p\n", inputFS, recloc) );
        dprintf( ("recbld = |%s|\n", record) );
        donerec = 1;
 }
index cfd456a..c9bfda2 100644 (file)
@@ -22,15 +22,15 @@ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
 USE OR PERFORMANCE OF THIS SOFTWARE.
 ****************************************************************/
 
-char   *version = "version May 27, 1996";
+char   *version = "version June 29, 1996";
 
 #define DEBUG
 #include <stdio.h>
 #include <ctype.h>
+#include <locale.h>
 #include <stdlib.h>
 #include <string.h>
 #include <signal.h>
-#include <locale.h>
 #include "awk.h"
 #include "awkgram.h"
 
index 480173e..fa540f6 100644 (file)
@@ -108,7 +108,7 @@ Cell *execute(Node *u)      /* execute a node of the parse tree */
        for (a = u; ; a = a->nnext) {
                curnode = a;
                if (isvalue(a)) {
-                       x = (Cell *)(a->narg[0]);
+                       x = (Cell *) (a->narg[0]);
                        if ((x->tval & FLD) && !donefld)
                                fldbld();
                        else if ((x->tval & REC) && !donerec)
@@ -353,8 +353,6 @@ Cell *getline(Node **a, int n)      /* get next line from specific input */
                x = execute(a[2]);              /* filename */
                if ((int) a[1] == '|')  /* input pipe */
                        a[1] = (Node *) LE;     /* arbitrary flag */
-               if ((x->tval & STR) == 0)
-                       x = copycell(x);
                fp = openfile((int) a[1], getsval(x));
                tempfree(x);
                if (fp == NULL)
@@ -407,8 +405,6 @@ Cell *array(Node **a, int n)        /* a[0] is symtab, a[1] is list of subscripts */
        buf[0] = 0;
        for (np = a[1]; np; np = np->nnext) {
                y = execute(np);        /* subscript */
-               if ((y->tval & STR) == 0)
-                       y = copycell(y);
                s = getsval(y);
                strcat(buf, s);         /* BUG: unchecked! */
                if (np->nnext)
@@ -448,8 +444,6 @@ Cell *adelete(Node **a, int n)      /* a[0] is symtab, a[1] is list of subscripts */
                buf[0] = 0;
                for (np = a[1]; np; np = np->nnext) {
                        y = execute(np);        /* subscript */
-                       if ((y->tval & STR) == 0)
-                               y = copycell(y);
                        s = getsval(y);
                        strcat(buf, s);
                        if (np->nnext)
@@ -481,8 +475,6 @@ Cell *intest(Node **a, int n)       /* a[0] is index (list), a[1] is symtab */
        buf[0] = 0;
        for (p = a[0]; p; p = p->nnext) {
                x = execute(p); /* expr */
-               if ((x->tval & STR) == 0)
-                       x = copycell(x);
                s = getsval(x);
                strcat(buf, s);
                tempfree(x);
@@ -511,15 +503,11 @@ Cell *matchop(Node **a, int n)    /* ~ and match() */
                mode = 1;
        }
        x = execute(a[1]);      /* a[1] = target text */
-       if ((x->tval & STR) == 0)
-               x = copycell(x);
        s = getsval(x);
        if (a[0] == 0)          /* a[1] == 0: already-compiled reg expr */
                i = (*mf)((fa *) a[2], s);
        else {
                y = execute(a[2]);      /* a[2] = regular expr */
-               if ((y->tval & STR) == 0)
-                       y = copycell(y);
                t = getsval(y);
                pfa = makedfa(t, mode);
                i = (*mf)(pfa, s);
@@ -587,10 +575,6 @@ Cell *relop(Node **a, int n)       /* a[0 < a[1], etc. */
                j = x->fval - y->fval;
                i = j<0? -1: (j>0? 1: 0);
        } else {
-               if ((x->tval & STR) == 0)
-                       x = copycell(x);
-               if ((y->tval & STR) == 0)
-                       y = copycell(y);
                i = strcmp(getsval(x), getsval(y));
        }
        tempfree(x);
@@ -649,8 +633,6 @@ Cell *indirect(Node **a, int n)     /* $( a[0] ) */
        char *s;
 
        x = execute(a[0]);
-       if ((x->tval & STR) == 0)
-               x = copycell(x);
        m = getfval(x);
        if (m == 0 && !isnumber(s = getsval(x)))        /* suspicion! */
                ERROR "illegal field $(%s), name \"%s\"", s, x->nval FATAL;
@@ -674,8 +656,6 @@ Cell *substr(Node **a, int nnn)             /* substr(a[0], a[1], a[2]) */
        y = execute(a[1]);
        if (a[2] != 0)
                z = execute(a[2]);
-       if ((x->tval & STR) == 0)
-               x = copycell(x);
        s = getsval(x);
        k = strlen(s) + 1;
        if (k <= 1) {
@@ -719,12 +699,8 @@ Cell *sindex(Node **a, int nnn)            /* index(a[0], a[1]) */
        Awkfloat v = 0.0;
 
        x = execute(a[0]);
-       if ((x->tval & STR) == 0)
-               x = copycell(x);
        s1 = getsval(x);
        y = execute(a[1]);
-       if ((y->tval & STR) == 0)
-               y = copycell(y);
        s2 = getsval(y);
 
        z = gettemp();
@@ -805,8 +781,6 @@ int format(char *buf, int bufsize, char *s, Node *a)        /* printf-like conversions
                if (a == NULL)
                        ERROR "not enough args in printf(%s)", os FATAL;
                x = execute(a);
-               if ((x->tval & STR) == 0)
-                       x = copycell(x);
                a = a->nnext;
                switch (flag) {
                case 0: sprintf((char *)p, "%s", fmt);  /* unknown, so dump it too */
@@ -847,8 +821,6 @@ Cell *awksprintf(Node **a, int n)           /* sprintf(a[0]) */
 
        y = a[0]->nnext;
        x = execute(a[0]);
-       if ((x->tval & STR) == 0)
-               x = copycell(x);
        if (format(buf, sizeof buf, getsval(x), y) == -1)
                ERROR "sprintf string %.30s... too long", buf FATAL;
        tempfree(x);
@@ -868,8 +840,6 @@ Cell *awkprintf(Node **a, int n)            /* printf */
 
        y = a[0]->nnext;
        x = execute(a[0]);
-       if ((x->tval & STR) == 0)
-               x = copycell(x);
        if (format(buf, sizeof buf, getsval(x), y) == -1)
                ERROR "printf string %.30s... too long", buf FATAL;
        tempfree(x);
@@ -894,14 +864,10 @@ Cell *arith(Node **a, int n)      /* a[0] + a[1], etc.  also -a[0] */
        Cell *x, *y, *z;
 
        x = execute(a[0]);
-       if ((x->tval & NUM) == 0)
-               x = copycell(x);
        i = getfval(x);
        tempfree(x);
        if (n != UMINUS) {
                y = execute(a[1]);
-               if ((y->tval & NUM) == 0)
-                       y = copycell(y);
                j = getfval(y);
                tempfree(y);
        }
@@ -1047,10 +1013,6 @@ Cell *cat(Node **a, int q)       /* a[0] cat a[1] */
 
        x = execute(a[0]);
        y = execute(a[1]);
-       if ((x->tval & STR) == 0)
-               x = copycell(x);
-       if ((y->tval & STR) == 0)
-               y = copycell(y);
        getsval(x);
        getsval(y);
        n1 = strlen(x->sval);
@@ -1117,15 +1079,11 @@ Cell *split(Node **a, int nnn)  /* split(a[0], a[1], a[2]); a[3] is type */
        int n, tempstat;
 
        y = execute(a[0]);      /* source string */
-       if ((y->tval & STR) == 0)
-               y = copycell(y);
        s = getsval(y);
        if (a[2] == 0)          /* fs string */
                fs = *FS;
        else if ((int) a[3] == STRING) {        /* split(str,arr,"string") */
                x = execute(a[2]);
-               if ((x->tval & STR) == 0)
-                       x = copycell(x);
                fs = getsval(x);
        } else if ((int) a[3] == REGEXPR)
                fs = (char*) "(regexpr)";       /* split(str,arr,/regexpr/) */
@@ -1433,8 +1391,6 @@ Cell *bltin(Node **a, int n)      /* builtin functions. a[0] is type, a[1] is arg lis
        nextarg = a[1]->nnext;
        switch (t) {
        case FLENGTH:
-               if ((x->tval & STR) == 0)
-                       x = copycell(x);
                u = strlen(getsval(x)); break;
        case FLOG:
                u = errcheck(log(getfval(x)), "log"); break;
@@ -1461,8 +1417,6 @@ Cell *bltin(Node **a, int n)      /* builtin functions. a[0] is type, a[1] is arg lis
                break;
        case FSYSTEM:
                fflush(stdout);         /* in case something is buffered already */
-               if ((x->tval & STR) == 0)
-                       x = copycell(x);
                u = (Awkfloat) system((char *)getsval(x)) / 256;   /* 256 is unix-dep */
                break;
        case FRAND:
@@ -1478,8 +1432,6 @@ Cell *bltin(Node **a, int n)      /* builtin functions. a[0] is type, a[1] is arg lis
                break;
        case FTOUPPER:
        case FTOLOWER:
-               if ((x->tval & STR) == 0)
-                       x = copycell(x);
                strcpy(buf, getsval(x));
                if (t == FTOUPPER) {
                        for (p = buf; *p; p++)
@@ -1495,8 +1447,6 @@ Cell *bltin(Node **a, int n)      /* builtin functions. a[0] is type, a[1] is arg lis
                setsval(x, buf);
                return x;
        case FFLUSH:
-               if ((x->tval & STR) == 0)
-                       x = copycell(x);
                if ((fp = openfile(GT, getsval(x))) == NULL)
                        u = EOF;
                else
@@ -1519,8 +1469,6 @@ Cell *bltin(Node **a, int n)      /* builtin functions. a[0] is type, a[1] is arg lis
 
 Cell *printstat(Node **a, int n)       /* print a[0] */
 {
-       extern char **OFMT, **CONVFMT;
-       char **save;
        Node *x;
        Cell *y;
        FILE *fp;
@@ -1531,12 +1479,7 @@ Cell *printstat(Node **a, int n) /* print a[0] */
                fp = redirect((int)a[1], a[2]);
        for (x = a[0]; x != NULL; x = x->nnext) {
                y = execute(x);
-               if ((y->tval & STR) == 0)
-                       y = copycell(y);
-               save = CONVFMT;
-               CONVFMT = OFMT;
                fputs((char *)getsval(y), fp);
-               CONVFMT = save;
                tempfree(y);
                if (x->nnext == NULL)
                        fputs((char *)*ORS, fp);
@@ -1565,8 +1508,6 @@ FILE *redirect(int a, Node *b)    /* set up all i/o redirections */
        char *fname;
 
        x = execute(b);
-       if ((x->tval & STR) == 0)
-               x = copycell(x);
        fname = getsval(x);
        fp = openfile(a, fname);
        if (fp == NULL)
@@ -1642,8 +1583,6 @@ Cell *closefile(Node **a, int n)
 
        n = 0;
        x = execute(a[0]);
-       if ((x->tval & STR) == 0)
-               x = copycell(x);
        getsval(x);
        for (i = 0; i < FOPEN_MAX; i++)
                if (files[i].fname && strcmp(x->sval, files[i].fname) == 0) {
@@ -1691,8 +1630,6 @@ Cell *sub(Node **a, int nnn)      /* substitute command */
        fa *pfa;
 
        x = execute(a[3]);      /* target string */
-       if ((x->tval & STR) == 0)
-               x = copycell(x);
        t = getsval(x);
        if (a[0] == 0)          /* 0 => a[1] is already-compiled regexpr */
                pfa = (fa *) a[1];      /* regular expression */
@@ -1702,8 +1639,6 @@ Cell *sub(Node **a, int nnn)      /* substitute command */
                tempfree(y);
        }
        y = execute(a[2]);      /* replacement string */
-       if ((y->tval & STR) == 0)
-               y = copycell(y);
        result = false;
        if (pmatch(pfa, t)) {
                pb = buf;
@@ -1749,21 +1684,15 @@ Cell *gsub(Node **a, int nnn)   /* global substitute */
        mflag = 0;      /* if mflag == 0, can replace empty string */
        num = 0;
        x = execute(a[3]);      /* target string */
-       if ((x->tval & STR) == 0)
-               x = copycell(x);
        t = getsval(x);
        if (a[0] == 0)          /* 0 => a[1] is already-compiled regexpr */
                pfa = (fa *) a[1];      /* regular expression */
        else {
                y = execute(a[1]);
-               if ((y->tval & STR) == 0)
-                       y = copycell(y);
                pfa = makedfa(getsval(y), 1);
                tempfree(y);
        }
        y = execute(a[2]);      /* replacement string */
-       if ((y->tval & STR) == 0)
-               y = copycell(y);
        if (pmatch(pfa, t)) {
                tempstat = pfa->initstat;
                pfa->initstat = 2;
index 973e355..86ca9ea 100644 (file)
@@ -82,7 +82,7 @@ void syminit(void)    /* initialize symbol table with builtin vars */
        ORS = &setsymtab("ORS", "\n", 0.0, STR|DONTFREE, symtab)->sval;
        OFMT = &setsymtab("OFMT", "%.6g", 0.0, STR|DONTFREE, symtab)->sval;
        CONVFMT = &setsymtab("CONVFMT", "%.6g", 0.0, STR|DONTFREE, symtab)->sval;
-       FILENAME = &setsymtab("FILENAME", "-", 0.0, STR|DONTFREE, symtab)->sval;
+       FILENAME = &setsymtab("FILENAME", "", 0.0, STR|DONTFREE, symtab)->sval;
        nfloc = setsymtab("NF", "", 0.0, NUM, symtab);
        NF = &nfloc->fval;
        nrloc = setsymtab("NR", "", 0.0, NUM, symtab);