summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>1997-01-20 19:43:25 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>1997-01-20 19:43:25 +0000
commitf7e578b681f2047c43e6d75930fb5f278543dc32 (patch)
tree71e7f54a3183f4732b8ae0271c305720236851a4
parent0f2a4655788de684b2544b1175a3aeb883569249 (diff)
Latest research awk from June 29, 1996
-rw-r--r--usr.bin/awk/FIXES17
-rw-r--r--usr.bin/awk/OpenBSD-PATCHES384
-rw-r--r--usr.bin/awk/awk.112
-rw-r--r--usr.bin/awk/awk.h1
-rw-r--r--usr.bin/awk/awklex.l34
-rw-r--r--usr.bin/awk/b.c7
-rw-r--r--usr.bin/awk/lib.c14
-rw-r--r--usr.bin/awk/main.c4
-rw-r--r--usr.bin/awk/run.c73
-rw-r--r--usr.bin/awk/tran.c2
10 files changed, 443 insertions, 105 deletions
diff --git a/usr.bin/awk/FIXES b/usr.bin/awk/FIXES
index 9ac0b21ac16..9cda6ca12b3 100644
--- a/usr.bin/awk/FIXES
+++ b/usr.bin/awk/FIXES
@@ -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
index 00000000000..b011fb71ed0
--- /dev/null
+++ b/usr.bin/awk/OpenBSD-PATCHES
@@ -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 */
diff --git a/usr.bin/awk/awk.1 b/usr.bin/awk/awk.1
index 54b4d3b79d8..c2328aee911 100644
--- a/usr.bin/awk/awk.1
+++ b/usr.bin/awk/awk.1
@@ -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
diff --git a/usr.bin/awk/awk.h b/usr.bin/awk/awk.h
index 731f6f13cab..213e43302c8 100644
--- a/usr.bin/awk/awk.h
+++ b/usr.bin/awk/awk.h
@@ -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;
diff --git a/usr.bin/awk/awklex.l b/usr.bin/awk/awklex.l
index d7ea2357e08..a179a7d074a 100644
--- a/usr.bin/awk/awklex.l
+++ b/usr.bin/awk/awklex.l
@@ -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; }
%%
diff --git a/usr.bin/awk/b.c b/usr.bin/awk/b.c
index 3baab2ac071..9952d94ed35 100644
--- a/usr.bin/awk/b.c
+++ b/usr.bin/awk/b.c
@@ -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 */
diff --git a/usr.bin/awk/lib.c b/usr.bin/awk/lib.c
index 6f72be9133a..613e8f0c712 100644
--- a/usr.bin/awk/lib.c
+++ b/usr.bin/awk/lib.c
@@ -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;
}
diff --git a/usr.bin/awk/main.c b/usr.bin/awk/main.c
index cfd456a1b52..c9bfda2bd39 100644
--- a/usr.bin/awk/main.c
+++ b/usr.bin/awk/main.c
@@ -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"
diff --git a/usr.bin/awk/run.c b/usr.bin/awk/run.c
index 480173e8539..fa540f634e2 100644
--- a/usr.bin/awk/run.c
+++ b/usr.bin/awk/run.c
@@ -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;
diff --git a/usr.bin/awk/tran.c b/usr.bin/awk/tran.c
index 973e355765f..86ca9ead221 100644
--- a/usr.bin/awk/tran.c
+++ b/usr.bin/awk/tran.c
@@ -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);