Update to a 26-Nov-2009 release.
This commit is contained in:
parent
375bdd5dd9
commit
07b41d1dea
@ -25,6 +25,23 @@ THIS SOFTWARE.
|
||||
This file lists all bug fixes, changes, etc., made since the AWK book
|
||||
was sent to the printers in August, 1987.
|
||||
|
||||
Nov 26, 2009:
|
||||
fixed a long-standing issue with when FS takes effect. a
|
||||
change to FS is now noticed immediately for subsequent splits.
|
||||
|
||||
changed the name getline() to awkgetline() to avoid yet another
|
||||
name conflict somewhere.
|
||||
|
||||
Feb 11, 2009:
|
||||
temporarily for now defined HAS_ISBLANK, since that seems to
|
||||
be the best way through the thicket. isblank arrived in C99,
|
||||
but seems to be arriving at different systems at different
|
||||
times.
|
||||
|
||||
Oct 8, 2008:
|
||||
fixed typo in b.c that set tmpvec wrongly. no one had ever
|
||||
run into the problem, apparently. thanks to alistair crooks.
|
||||
|
||||
Oct 23, 2007:
|
||||
minor fix in lib.c: increase inputFS to 100, change malloc
|
||||
for fields to n+1.
|
||||
|
@ -24,6 +24,9 @@ THIS SOFTWARE.
|
||||
|
||||
/* lasciate ogne speranza, voi ch'intrate. */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#include <ctype.h>
|
||||
@ -285,9 +288,21 @@ int quoted(char **pp) /* pick up next thing after a \\ */
|
||||
return c;
|
||||
}
|
||||
|
||||
static int collate_range_cmp(int a, int b)
|
||||
{
|
||||
static char s[2][2];
|
||||
|
||||
if ((uschar)a == (uschar)b)
|
||||
return 0;
|
||||
s[0][0] = a;
|
||||
s[1][0] = b;
|
||||
return (strcoll(s[0], s[1]));
|
||||
}
|
||||
|
||||
char *cclenter(const char *argp) /* add a character class */
|
||||
{
|
||||
int i, c, c2;
|
||||
int j;
|
||||
uschar *p = (uschar *) argp;
|
||||
uschar *op, *bp;
|
||||
static uschar *buf = 0;
|
||||
@ -306,15 +321,18 @@ char *cclenter(const char *argp) /* add a character class */
|
||||
c2 = *p++;
|
||||
if (c2 == '\\')
|
||||
c2 = quoted((char **) &p);
|
||||
if (c > c2) { /* empty; ignore */
|
||||
if (collate_range_cmp(c, c2) > 0) {
|
||||
bp--;
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
while (c < c2) {
|
||||
for (j = 0; j < NCHARS; j++) {
|
||||
if ((collate_range_cmp(c, j) > 0) ||
|
||||
collate_range_cmp(j, c2) > 0)
|
||||
continue;
|
||||
if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "cclenter1"))
|
||||
FATAL("out of space for character class [%.10s...] 2", p);
|
||||
*bp++ = ++c;
|
||||
*bp++ = j;
|
||||
i++;
|
||||
}
|
||||
continue;
|
||||
@ -731,6 +749,7 @@ Node *unary(Node *np)
|
||||
* to nelson beebe for the suggestion; let's see if it works everywhere.
|
||||
*/
|
||||
|
||||
/* #define HAS_ISBLANK */
|
||||
#ifndef HAS_ISBLANK
|
||||
|
||||
int (isblank)(int c)
|
||||
@ -876,7 +895,7 @@ int cgoto(fa *f, int s, int c)
|
||||
if (q[j] >= maxsetvec) {
|
||||
maxsetvec *= 4;
|
||||
setvec = (int *) realloc(setvec, maxsetvec * sizeof(int));
|
||||
tmpset = (int *) realloc(setvec, maxsetvec * sizeof(int));
|
||||
tmpset = (int *) realloc(tmpset, maxsetvec * sizeof(int));
|
||||
if (setvec == 0 || tmpset == 0)
|
||||
overflo("cgoto overflow");
|
||||
}
|
||||
|
@ -274,6 +274,7 @@ void fldbld(void) /* create fields from current record */
|
||||
}
|
||||
fr = fields;
|
||||
i = 0; /* number of fields accumulated here */
|
||||
strcpy(inputFS, *FS);
|
||||
if (strlen(inputFS) > 1) { /* it's a regular expression */
|
||||
i = refldbld(r, inputFS);
|
||||
} else if ((sep = *inputFS) == ' ') { /* default whitespace */
|
||||
|
@ -1,73 +0,0 @@
|
||||
Note added June, 2002:
|
||||
|
||||
With the advent of OS X, life is simpler: if you have the developer
|
||||
tools installed, the standard awk makefile and gcc works fine, and
|
||||
you can ignore the rest of this file, which is now hereby deprecated.
|
||||
|
||||
|
||||
|
||||
|
||||
This file contains a make shell script and a version of the file
|
||||
missing95.c for the Mac, courtesy of Dan Allen.
|
||||
|
||||
make shell script:
|
||||
|
||||
# MPW Shell script to build Awk using Apple's MRC compiler.
|
||||
# 22 Jan 1999 - Created by Dan Allen.
|
||||
# 25 Mar 1999 - Updated for newer Awk.
|
||||
#
|
||||
# Porting notes for the Mac:
|
||||
#
|
||||
# 1. main in main.c needs to have its prototype changed to:
|
||||
#
|
||||
# int main(int argc, char *argv[], char *environ[])
|
||||
#
|
||||
# 2. popen and pclose in missing95.c need to have as their body the
|
||||
# older style
|
||||
#
|
||||
# return NULL;
|
||||
#
|
||||
# as parallel pipes are not supported by MPW.
|
||||
#
|
||||
# 3. To make your Mac more responsive while long awk scripts run,
|
||||
# you may want to add some SpinCursor calls to support cooperative multitasking.
|
||||
#
|
||||
# All of these minor changes can be put under "#ifdef powerc" for portability's sake.
|
||||
#
|
||||
#
|
||||
|
||||
If {1} == "clean"
|
||||
Delete -i awk maketab maketab.c.o ytab.c.o b.c.o main.c.o parse.c.o proctab.c proctab.c.o tran.c.o lib.c.o run.c.o lex.c.o missing95.c.o
|
||||
Else
|
||||
MRC ytab.c -w off -opt speed
|
||||
MRC b.c -w off -opt speed
|
||||
MRC main.c -w off -opt speed
|
||||
MRC parse.c -w off -opt speed
|
||||
MRC maketab.c -w off -opt speed
|
||||
PPCLink -o maketab maketab.c.o "{PPCLibraries}InterfaceLib" "{PPCLibraries}MathLib" "{PPCLibraries}StdCLib" "{PPCLibraries}StdCRuntime.o" "{PPCLibraries}PPCCRuntime.o" "{PPCLibraries}PPCToolLibs.o" -t MPST -c 'MPS '
|
||||
maketab > proctab.c
|
||||
MRC proctab.c -w off -opt speed
|
||||
MRC tran.c -w off -opt speed
|
||||
MRC lib.c -w off -opt speed
|
||||
MRC run.c -w off -opt speed
|
||||
MRC lex.c -w off -opt speed
|
||||
MRC missing95.c -w off -opt speed
|
||||
PPCLink -o awk ytab.c.o b.c.o main.c.o parse.c.o proctab.c.o tran.c.o lib.c.o run.c.o lex.c.o missing95.c.o "{PPCLibraries}InterfaceLib" "{PPCLibraries}MathLib" "{PPCLibraries}StdCLib" "{PPCLibraries}StdCRuntime.o" "{PPCLibraries}PPCCRuntime.o" "{PPCLibraries}PPCToolLibs.o" -d
|
||||
SetFile awk -d . -m . -t MPST -c 'MPS '
|
||||
End
|
||||
|
||||
|
||||
missing95.c for the Mac:
|
||||
|
||||
/* popen and pclose are not available on the Mac. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
FILE *popen(char *s, char *m) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int pclose(FILE *f) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -22,7 +22,10 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
****************************************************************/
|
||||
|
||||
const char *version = "version 20070501";
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
const char *version = "version 20091126 (FreeBSD)";
|
||||
|
||||
#define DEBUG
|
||||
#include <stdio.h>
|
||||
@ -58,6 +61,7 @@ int main(int argc, char *argv[])
|
||||
const char *fs = NULL;
|
||||
|
||||
setlocale(LC_CTYPE, "");
|
||||
setlocale(LC_COLLATE, "");
|
||||
setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
|
||||
cmdname = argv[0];
|
||||
if (argc == 1) {
|
||||
@ -86,13 +90,18 @@ int main(int argc, char *argv[])
|
||||
safe = 1;
|
||||
break;
|
||||
case 'f': /* next argument is program filename */
|
||||
argc--;
|
||||
argv++;
|
||||
if (argc <= 1)
|
||||
FATAL("no program filename");
|
||||
if (npfile >= MAX_PFILE - 1)
|
||||
FATAL("too many -f options");
|
||||
pfile[npfile++] = argv[1];
|
||||
if (argv[1][2] != 0) { /* arg is -fsomething */
|
||||
if (npfile >= MAX_PFILE - 1)
|
||||
FATAL("too many -f options");
|
||||
pfile[npfile++] = &argv[1][2];
|
||||
} else { /* arg is -f something */
|
||||
argc--; argv++;
|
||||
if (argc <= 1)
|
||||
FATAL("no program filename");
|
||||
if (npfile >= MAX_PFILE - 1)
|
||||
FATAL("too many -f options");
|
||||
pfile[npfile++] = argv[1];
|
||||
}
|
||||
break;
|
||||
case 'F': /* set field separator */
|
||||
if (argv[1][2] != 0) { /* arg is -Fsomething */
|
||||
@ -111,8 +120,14 @@ int main(int argc, char *argv[])
|
||||
WARNING("field separator FS is empty");
|
||||
break;
|
||||
case 'v': /* -v a=1 to be done NOW. one -v for each */
|
||||
if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
|
||||
setclvar(argv[1]);
|
||||
if (argv[1][2] != 0) { /* arg is -vsomething */
|
||||
if (argv[1][2] != 0)
|
||||
setclvar(&argv[1][2]);
|
||||
} else { /* arg is -v something */
|
||||
argc--; argv++;
|
||||
if (argc > 1 && isclvar(argv[1]))
|
||||
setclvar(argv[1]);
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
dbg = atoi(&argv[1][2]);
|
||||
|
@ -31,7 +31,6 @@ CC = gcc -fprofile-arcs -ftest-coverage # then gcov f1.c; cat f1.c.gcov
|
||||
CC = gcc -Wall -g
|
||||
CC = cc
|
||||
CC = gcc -O4
|
||||
CC = gcc -Wall -g
|
||||
|
||||
|
||||
YACC = bison -y
|
||||
|
@ -102,7 +102,7 @@ struct xx
|
||||
{ CALL, "call", "call" },
|
||||
{ ARG, "arg", "arg" },
|
||||
{ VARNF, "getnf", "NF" },
|
||||
{ GETLINE, "getline", "getline" },
|
||||
{ GETLINE, "awkgetline", "getline" },
|
||||
{ 0, "", "" },
|
||||
};
|
||||
|
||||
|
@ -180,7 +180,7 @@ Cell *(*proctab[93])(Node **, int) = {
|
||||
nullproc, /* NUMBER */
|
||||
nullproc, /* STRING */
|
||||
nullproc, /* REGEXPR */
|
||||
getline, /* GETLINE */
|
||||
awkgetline, /* GETLINE */
|
||||
substr, /* SUBSTR */
|
||||
split, /* SPLIT */
|
||||
jump, /* RETURN */
|
||||
|
@ -149,7 +149,7 @@ extern Cell *call(Node **, int);
|
||||
extern Cell *copycell(Cell *);
|
||||
extern Cell *arg(Node **, int);
|
||||
extern Cell *jump(Node **, int);
|
||||
extern Cell *getline(Node **, int);
|
||||
extern Cell *awkgetline(Node **, int);
|
||||
extern Cell *getnf(Node **, int);
|
||||
extern Cell *array(Node **, int);
|
||||
extern Cell *awkdelete(Node **, int);
|
||||
|
@ -22,6 +22,9 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
****************************************************************/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#define DEBUG
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
@ -388,7 +391,7 @@ Cell *jump(Node **a, int n) /* break, continue, next, nextfile, return */
|
||||
return 0; /* not reached */
|
||||
}
|
||||
|
||||
Cell *getline(Node **a, int n) /* get next line from specific input */
|
||||
Cell *awkgetline(Node **a, int n) /* get next line from specific input */
|
||||
{ /* a[0] is variable, a[1] is operator, a[2] is filename */
|
||||
Cell *r, *x;
|
||||
extern Cell **fldtab;
|
||||
@ -653,7 +656,7 @@ 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 {
|
||||
i = strcmp(getsval(x), getsval(y));
|
||||
i = strcoll(getsval(x), getsval(y));
|
||||
}
|
||||
tempfree(x);
|
||||
tempfree(y);
|
||||
@ -1159,11 +1162,11 @@ Cell *cat(Node **a, int q) /* a[0] cat a[1] */
|
||||
x->sval, y->sval);
|
||||
strcpy(s, x->sval);
|
||||
strcpy(s+n1, y->sval);
|
||||
tempfree(x);
|
||||
tempfree(y);
|
||||
z = gettemp();
|
||||
z->sval = s;
|
||||
z->tval = STR;
|
||||
tempfree(x);
|
||||
return(z);
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,8 @@ SRCS= awkgram.y b.c lex.c lib.c main.c parse.c proctab.c run.c tran.c ytab.h
|
||||
|
||||
CFLAGS+= -DHAS_ISBLANK -I. -I${AWKSRC} -DFOPEN_MAX=64
|
||||
|
||||
WARNS?= 1
|
||||
|
||||
DPADD= ${LIBM}
|
||||
LDADD= -lm
|
||||
|
||||
@ -25,10 +27,4 @@ proctab.c: maketab
|
||||
build-tools: maketab
|
||||
maketab: ytab.h ${AWKSRC}/maketab.c
|
||||
|
||||
.for f in b.c main.c run.c
|
||||
${f}: ${AWKSRC}/${f} ${.CURDIR}/${f}.diff
|
||||
patch -s -b .orig -o ${.TARGET} < ${.CURDIR}/${f}.diff ${AWKSRC}/${f}
|
||||
CLEANFILES+= ${f}
|
||||
.endfor
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -1,53 +0,0 @@
|
||||
$FreeBSD$
|
||||
|
||||
Index: b.c
|
||||
===================================================================
|
||||
RCS file: /home/ncvs/src/contrib/one-true-awk/b.c,v
|
||||
retrieving revision 1.1.1.8
|
||||
diff -u -p -r1.1.1.8 b.c
|
||||
--- b.c 16 May 2005 19:11:31 -0000 1.1.1.8
|
||||
+++ b.c 16 May 2005 19:12:40 -0000
|
||||
@@ -282,9 +282,21 @@ int quoted(char **pp) /* pick up next th
|
||||
return c;
|
||||
}
|
||||
|
||||
+static int collate_range_cmp(int a, int b)
|
||||
+{
|
||||
+ static char s[2][2];
|
||||
+
|
||||
+ if ((uschar)a == (uschar)b)
|
||||
+ return 0;
|
||||
+ s[0][0] = a;
|
||||
+ s[1][0] = b;
|
||||
+ return (strcoll(s[0], s[1]));
|
||||
+}
|
||||
+
|
||||
char *cclenter(const char *argp) /* add a character class */
|
||||
{
|
||||
int i, c, c2;
|
||||
+ int j;
|
||||
uschar *p = (uschar *) argp;
|
||||
uschar *op, *bp;
|
||||
static uschar *buf = 0;
|
||||
@@ -303,15 +315,18 @@ char *cclenter(const char *argp) /* add
|
||||
c2 = *p++;
|
||||
if (c2 == '\\')
|
||||
c2 = quoted((char **) &p);
|
||||
- if (c > c2) { /* empty; ignore */
|
||||
+ if (collate_range_cmp(c, c2) > 0) {
|
||||
bp--;
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
- while (c < c2) {
|
||||
+ for (j = 0; j < NCHARS; j++) {
|
||||
+ if ((collate_range_cmp(c, j) > 0) ||
|
||||
+ collate_range_cmp(j, c2) > 0)
|
||||
+ continue;
|
||||
if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "cclenter1"))
|
||||
FATAL("out of space for character class [%.10s...] 2", p);
|
||||
- *bp++ = ++c;
|
||||
+ *bp++ = j;
|
||||
i++;
|
||||
}
|
||||
continue;
|
@ -1,69 +0,0 @@
|
||||
$FreeBSD$
|
||||
|
||||
Index: main.c
|
||||
===================================================================
|
||||
RCS file: /home/ncvs/src/contrib/one-true-awk/main.c,v
|
||||
retrieving revision 1.1.1.10
|
||||
diff -u -p -r1.1.1.10 main.c
|
||||
--- main.c 16 May 2005 19:11:31 -0000 1.1.1.10
|
||||
+++ main.c 15 Sep 2006 13:21:30 -0000
|
||||
@@ -22,7 +22,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE
|
||||
THIS SOFTWARE.
|
||||
****************************************************************/
|
||||
|
||||
-const char *version = "version 20070501";
|
||||
+const char *version = "version 20070501 (FreeBSD)";
|
||||
|
||||
#define DEBUG
|
||||
#include <stdio.h>
|
||||
@@ -58,6 +58,7 @@ int main(int argc, char *argv[])
|
||||
const char *fs = NULL;
|
||||
|
||||
setlocale(LC_CTYPE, "");
|
||||
+ setlocale(LC_COLLATE, "");
|
||||
setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
|
||||
cmdname = argv[0];
|
||||
if (argc == 1) {
|
||||
@@ -79,13 +80,18 @@ int main(int argc, char *argv[])
|
||||
safe = 1;
|
||||
break;
|
||||
case 'f': /* next argument is program filename */
|
||||
- argc--;
|
||||
- argv++;
|
||||
- if (argc <= 1)
|
||||
- FATAL("no program filename");
|
||||
- if (npfile >= MAX_PFILE - 1)
|
||||
- FATAL("too many -f options");
|
||||
- pfile[npfile++] = argv[1];
|
||||
+ if (argv[1][2] != 0) { /* arg is -fsomething */
|
||||
+ if (npfile >= MAX_PFILE - 1)
|
||||
+ FATAL("too many -f options");
|
||||
+ pfile[npfile++] = &argv[1][2];
|
||||
+ } else { /* arg is -f something */
|
||||
+ argc--; argv++;
|
||||
+ if (argc <= 1)
|
||||
+ FATAL("no program filename");
|
||||
+ if (npfile >= MAX_PFILE - 1)
|
||||
+ FATAL("too many -f options");
|
||||
+ pfile[npfile++] = argv[1];
|
||||
+ }
|
||||
break;
|
||||
case 'F': /* set field separator */
|
||||
if (argv[1][2] != 0) { /* arg is -Fsomething */
|
||||
@@ -104,8 +110,14 @@ int main(int argc, char *argv[])
|
||||
WARNING("field separator FS is empty");
|
||||
break;
|
||||
case 'v': /* -v a=1 to be done NOW. one -v for each */
|
||||
- if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
|
||||
- setclvar(argv[1]);
|
||||
+ if (argv[1][2] != 0) { /* arg is -vsomething */
|
||||
+ if (argv[1][2] != 0)
|
||||
+ setclvar(&argv[1][2]);
|
||||
+ } else { /* arg is -v something */
|
||||
+ argc--; argv++;
|
||||
+ if (argc > 1 && isclvar(argv[1]))
|
||||
+ setclvar(argv[1]);
|
||||
+ }
|
||||
break;
|
||||
case 'm': /* more memory: -mr=record, -mf=fields */
|
||||
/* no longer supported */
|
@ -1,18 +0,0 @@
|
||||
$FreeBSD$
|
||||
|
||||
Index: run.c
|
||||
===================================================================
|
||||
RCS file: /home/ncvs/src/contrib/one-true-awk/run.c,v
|
||||
retrieving revision 1.1.1.8
|
||||
diff -u -p -r1.1.1.8 run.c
|
||||
--- run.c 16 May 2005 19:11:35 -0000 1.1.1.8
|
||||
+++ run.c 16 May 2005 19:12:47 -0000
|
||||
@@ -651,7 +651,7 @@ Cell *relop(Node **a, int n) /* a[0 < a[
|
||||
j = x->fval - y->fval;
|
||||
i = j<0? -1: (j>0? 1: 0);
|
||||
} else {
|
||||
- i = strcmp(getsval(x), getsval(y));
|
||||
+ i = strcoll(getsval(x), getsval(y));
|
||||
}
|
||||
tempfree(x);
|
||||
tempfree(y);
|
Loading…
x
Reference in New Issue
Block a user