Vendor import of bwk's 29-Nov-2002 release.
Most significant update is the inclusion of our port's locale patches.
This commit is contained in:
parent
146a1e500c
commit
813da98d0e
@ -25,6 +25,43 @@ THIS SOFTWARE.
|
||||
This file lists all bug fixes, changes, etc., made since the AWK book
|
||||
was sent to the printers in August, 1987.
|
||||
|
||||
Nov 29, 2002:
|
||||
modified b.c (with tiny changes in main and run) to support
|
||||
locales, using strcoll and iswhatever tests for posix character
|
||||
classes. thanks to ruslan ermilov (ru@freebsd.org) for code.
|
||||
the function isblank doesn't seem to have propagated to any
|
||||
header file near me, so it's there explicitly. not properly
|
||||
tested on non-ascii character sets by me.
|
||||
|
||||
Jun 28, 2002:
|
||||
modified run/format() and tran/getsval() to do a slightly better
|
||||
job on using OFMT for output from print and CONVFMT for other
|
||||
number->string conversions, as promised by posix and done by
|
||||
gawk and mawk. there are still places where it doesn't work
|
||||
right if CONVFMT is changed; by then the STR attribute of the
|
||||
variable has been irrevocably set. thanks to arnold robbins for
|
||||
code and examples.
|
||||
|
||||
fixed subtle bug in format that could get core dump. thanks to
|
||||
Jaromir Dolecek <jdolecek@NetBSD.org> for finding and fixing.
|
||||
minor cleanup in run.c / format() at the same time.
|
||||
|
||||
added some tests for null pointers to debugging printf's, which
|
||||
were never intended for external consumption. thanks to dave
|
||||
kerns (dkerns@lucent.com) for pointing this out.
|
||||
|
||||
GNU compatibility: an empty regexp matches anything (thanks to
|
||||
dag-erling smorgrav, des@ofug.org). subject to reversion if
|
||||
this does more harm than good.
|
||||
|
||||
pervasive small changes to make things more const-correct, as
|
||||
reported by gcc's -Wwrite-strings. as it says in the gcc manual,
|
||||
this may be more nuisance than useful. provoked by a suggestion
|
||||
and code from arnaud desitter, arnaud@nimbus.geog.ox.ac.uk
|
||||
|
||||
minor documentation changes to note that this now compiles out
|
||||
of the box on Mac OS X.
|
||||
|
||||
Feb 10, 2002:
|
||||
changed types in posix chars structure to quiet solaris cc.
|
||||
|
||||
|
@ -40,18 +40,18 @@ which should produce a sequence of messages roughly like this:
|
||||
conflicts: 43 shift/reduce, 85 reduce/reduce
|
||||
mv y.tab.c ytab.c
|
||||
mv y.tab.h ytab.h
|
||||
cc -O -c ytab.c
|
||||
cc -O -c b.c
|
||||
cc -O -c main.c
|
||||
cc -O -c parse.c
|
||||
cc -O maketab.c -o maketab
|
||||
cc -c ytab.c
|
||||
cc -c b.c
|
||||
cc -c main.c
|
||||
cc -c parse.c
|
||||
cc maketab.c -o maketab
|
||||
./maketab >proctab.c
|
||||
cc -O -c proctab.c
|
||||
cc -O -c tran.c
|
||||
cc -O -c lib.c
|
||||
cc -O -c run.c
|
||||
cc -O -c lex.c
|
||||
cc -O ytab.o b.o main.o parse.o proctab.o tran.o lib.o run.o lex.o -lm
|
||||
cc -c proctab.c
|
||||
cc -c tran.c
|
||||
cc -c lib.c
|
||||
cc -c run.c
|
||||
cc -c lex.c
|
||||
cc ytab.o b.o main.o parse.o proctab.o tran.o lib.o run.o lex.o -lm
|
||||
|
||||
This produces an executable a.out; you will eventually want to
|
||||
move this to some place like /usr/bin/awk.
|
||||
@ -75,9 +75,14 @@ with, though the underlying support has mysterious properties,
|
||||
the symptom of which can be truncated pipe output. Beware.
|
||||
The file makefile.win gives hints on how to proceed.
|
||||
|
||||
This is also said to compile on Macintosh systems, using the
|
||||
This compiles without change on Macintosh OS X using gcc and
|
||||
the standard developer tools.
|
||||
|
||||
This is also said to compile on Macintosh OS 9 systems, using the
|
||||
file "buildmac" provided by Dan Allen (danallen@microsoft.com),
|
||||
to whom many thanks.
|
||||
|
||||
The version of malloc that comes with some systems is sometimes
|
||||
astonishly slow. If awk seems slow, you might try fixing that.
|
||||
More generally, turning on optimization can significantly improve
|
||||
awk's speed, perhaps by 1/3 for highest levels.
|
||||
|
@ -30,6 +30,8 @@ typedef unsigned char uschar;
|
||||
|
||||
#define xfree(a) { if ((a) != NULL) { free((char *) a); a = NULL; } }
|
||||
|
||||
#define NN(p) ((p) ? (p) : "(null)") /* guaranteed non-null for dprintf
|
||||
*/
|
||||
#define DEBUG
|
||||
#ifdef DEBUG
|
||||
/* uses have to be doubly parenthesized */
|
||||
|
@ -75,7 +75,7 @@ int patlen;
|
||||
fa *fatab[NFA];
|
||||
int nfatab = 0; /* entries in fatab */
|
||||
|
||||
fa *makedfa(char *s, int anchor) /* returns dfa for reg expr s */
|
||||
fa *makedfa(const char *s, int anchor) /* returns dfa for reg expr s */
|
||||
{
|
||||
int i, use, nuse;
|
||||
fa *pfa;
|
||||
@ -117,7 +117,7 @@ fa *makedfa(char *s, int anchor) /* returns dfa for reg expr s */
|
||||
return pfa;
|
||||
}
|
||||
|
||||
fa *mkdfa(char *s, int anchor) /* does the real work of making a dfa */
|
||||
fa *mkdfa(const char *s, int anchor) /* does the real work of making a dfa */
|
||||
/* anchor = 1 for anchored matches, else 0 */
|
||||
{
|
||||
Node *p, *p1;
|
||||
@ -282,9 +282,24 @@ int quoted(char **pp) /* pick up next thing after a \\ */
|
||||
return c;
|
||||
}
|
||||
|
||||
char *cclenter(char *argp) /* add a character class */
|
||||
static int collate_range_cmp(int a, int b)
|
||||
{
|
||||
int r;
|
||||
static char s[2][2];
|
||||
|
||||
if ((uschar)a == (uschar)b)
|
||||
return 0;
|
||||
s[0][0] = a;
|
||||
s[1][0] = b;
|
||||
if ((r = strcoll(s[0], s[1])) == 0)
|
||||
r = (uschar)a - (uschar)b;
|
||||
return r;
|
||||
}
|
||||
|
||||
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 +318,18 @@ char *cclenter(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) { /* empty; ignore */
|
||||
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, 0))
|
||||
FATAL("out of space for character class [%.10s...] 2", p);
|
||||
*bp++ = ++c;
|
||||
*bp++ = j;
|
||||
i++;
|
||||
}
|
||||
continue;
|
||||
@ -328,7 +346,7 @@ char *cclenter(char *argp) /* add a character class */
|
||||
return (char *) tostring((char *) buf);
|
||||
}
|
||||
|
||||
void overflo(char *s)
|
||||
void overflo(const char *s)
|
||||
{
|
||||
FATAL("regular expression too big: %.30s...", s);
|
||||
}
|
||||
@ -446,7 +464,7 @@ void follow(Node *v) /* collects leaves that can follow v into setvec */
|
||||
}
|
||||
}
|
||||
|
||||
int member(int c, char *sarg) /* is c in s? */
|
||||
int member(int c, const char *sarg) /* is c in s? */
|
||||
{
|
||||
uschar *s = (uschar *) sarg;
|
||||
|
||||
@ -456,7 +474,7 @@ int member(int c, char *sarg) /* is c in s? */
|
||||
return(0);
|
||||
}
|
||||
|
||||
int match(fa *f, char *p0) /* shortest match ? */
|
||||
int match(fa *f, const char *p0) /* shortest match ? */
|
||||
{
|
||||
int s, ns;
|
||||
uschar *p = (uschar *) p0;
|
||||
@ -475,7 +493,7 @@ int match(fa *f, char *p0) /* shortest match ? */
|
||||
return(0);
|
||||
}
|
||||
|
||||
int pmatch(fa *f, char *p0) /* longest match, for sub */
|
||||
int pmatch(fa *f, const char *p0) /* longest match, for sub */
|
||||
{
|
||||
int s, ns;
|
||||
uschar *p = (uschar *) p0;
|
||||
@ -528,7 +546,7 @@ int pmatch(fa *f, char *p0) /* longest match, for sub */
|
||||
return (0);
|
||||
}
|
||||
|
||||
int nematch(fa *f, char *p0) /* non-empty match, for sub */
|
||||
int nematch(fa *f, const char *p0) /* non-empty match, for sub */
|
||||
{
|
||||
int s, ns;
|
||||
uschar *p = (uschar *) p0;
|
||||
@ -580,15 +598,17 @@ int nematch(fa *f, char *p0) /* non-empty match, for sub */
|
||||
return (0);
|
||||
}
|
||||
|
||||
Node *reparse(char *p) /* parses regular expression pointed to by p */
|
||||
Node *reparse(const char *p) /* parses regular expression pointed to by p */
|
||||
{ /* uses relex() to scan regular expression */
|
||||
Node *np;
|
||||
|
||||
dprintf( ("reparse <%s>\n", p) );
|
||||
lastre = prestr = (uschar *) p; /* prestr points to string to be parsed */
|
||||
rtok = relex();
|
||||
/* GNU compatibility: an empty regexp matches anything */
|
||||
if (rtok == '\0')
|
||||
FATAL("empty regular expression");
|
||||
/* FATAL("empty regular expression"); previous */
|
||||
return(op2(ALL, NIL, NIL));
|
||||
np = regexp();
|
||||
if (rtok != '\0')
|
||||
FATAL("syntax error in regular expression %s at %s", lastre, prestr);
|
||||
@ -693,23 +713,24 @@ Node *unary(Node *np)
|
||||
* relex(), the expanded character class (prior to range expansion)
|
||||
* must be less than twice the size of their full name.
|
||||
*/
|
||||
|
||||
struct charclass {
|
||||
const char *cc_name;
|
||||
int cc_namelen;
|
||||
const char *cc_expand;
|
||||
int (*cc_func)(int);
|
||||
} charclasses[] = {
|
||||
{ "alnum", 5, "0-9A-Za-z" },
|
||||
{ "alpha", 5, "A-Za-z" },
|
||||
{ "blank", 5, " \t" },
|
||||
{ "cntrl", 5, "\000-\037\177" },
|
||||
{ "digit", 5, "0-9" },
|
||||
{ "graph", 5, "\041-\176" },
|
||||
{ "lower", 5, "a-z" },
|
||||
{ "print", 5, " \041-\176" },
|
||||
{ "punct", 5, "\041-\057\072-\100\133-\140\173-\176" },
|
||||
{ "space", 5, " \f\n\r\t\v" },
|
||||
{ "upper", 5, "A-Z" },
|
||||
{ "xdigit", 6, "0-9A-Fa-f" },
|
||||
{ "alnum", 5, isalnum },
|
||||
{ "alpha", 5, isalpha },
|
||||
{ "blank", 5, isblank },
|
||||
{ "cntrl", 5, iscntrl },
|
||||
{ "digit", 5, isdigit },
|
||||
{ "graph", 5, isgraph },
|
||||
{ "lower", 5, islower },
|
||||
{ "print", 5, isprint },
|
||||
{ "punct", 5, ispunct },
|
||||
{ "space", 5, isspace },
|
||||
{ "upper", 5, isupper },
|
||||
{ "xdigit", 6, isxdigit },
|
||||
{ NULL, 0, NULL },
|
||||
};
|
||||
|
||||
@ -722,7 +743,7 @@ int relex(void) /* lexical analyzer for reparse */
|
||||
static int bufsz = 100;
|
||||
uschar *bp;
|
||||
struct charclass *cc;
|
||||
const uschar *p;
|
||||
int i;
|
||||
|
||||
switch (c = *prestr++) {
|
||||
case '|': return OR;
|
||||
@ -771,8 +792,14 @@ int relex(void) /* lexical analyzer for reparse */
|
||||
if (cc->cc_name != NULL && prestr[1 + cc->cc_namelen] == ':' &&
|
||||
prestr[2 + cc->cc_namelen] == ']') {
|
||||
prestr += cc->cc_namelen + 3;
|
||||
for (p = (const uschar *) cc->cc_expand; *p; p++)
|
||||
*bp++ = *p;
|
||||
for (i = 0; i < NCHARS; i++) {
|
||||
if (!adjbuf((char **) &buf, &bufsz, bp-buf+1, 100, (char **) &bp, 0))
|
||||
FATAL("out of space for reg expr %.10s...", lastre);
|
||||
if (cc->cc_func(i)) {
|
||||
*bp++ = i;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
} else
|
||||
*bp++ = c;
|
||||
} else if (c == '\0') {
|
||||
|
@ -38,7 +38,7 @@ int brackcnt = 0;
|
||||
int parencnt = 0;
|
||||
|
||||
typedef struct Keyword {
|
||||
char *word;
|
||||
const char *word;
|
||||
int sub;
|
||||
int type;
|
||||
} Keyword;
|
||||
@ -499,7 +499,7 @@ int word(char *w)
|
||||
}
|
||||
}
|
||||
|
||||
void startreg(void) /* next call to yyles will return a regular expression */
|
||||
void startreg(void) /* next call to yylex will return a regular expression */
|
||||
{
|
||||
reg = 1;
|
||||
}
|
||||
@ -574,7 +574,7 @@ void unput(int c) /* put lexical character back on input */
|
||||
ep = ebuf + sizeof(ebuf) - 1;
|
||||
}
|
||||
|
||||
void unputstr(char *s) /* put a string back on input */
|
||||
void unputstr(const char *s) /* put a string back on input */
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -390,7 +390,7 @@ void growfldtab(int n) /* make new fields up to at least $n */
|
||||
nfields = nf;
|
||||
}
|
||||
|
||||
int refldbld(char *rec, char *fs) /* build fields from reg expr in FS */
|
||||
int refldbld(const char *rec, const char *fs) /* build fields from reg expr in FS */
|
||||
{
|
||||
/* this relies on having fields[] the same length as $0 */
|
||||
/* the fields are all stored in this one array with \0's */
|
||||
@ -475,12 +475,12 @@ void recbld(void) /* create $0 from $1..$NF if necessary */
|
||||
|
||||
int errorflag = 0;
|
||||
|
||||
void yyerror(char *s)
|
||||
void yyerror(const char *s)
|
||||
{
|
||||
SYNTAX(s);
|
||||
}
|
||||
|
||||
void SYNTAX(char *fmt, ...)
|
||||
void SYNTAX(const char *fmt, ...)
|
||||
{
|
||||
extern char *cmdname, *curfname;
|
||||
static int been_here = 0;
|
||||
@ -535,7 +535,7 @@ void bcheck2(int n, int c1, int c2)
|
||||
fprintf(stderr, "\t%d extra %c's\n", -n, c2);
|
||||
}
|
||||
|
||||
void FATAL(char *fmt, ...)
|
||||
void FATAL(const char *fmt, ...)
|
||||
{
|
||||
extern char *cmdname;
|
||||
va_list varg;
|
||||
@ -551,7 +551,7 @@ void FATAL(char *fmt, ...)
|
||||
exit(2);
|
||||
}
|
||||
|
||||
void WARNING(char *fmt, ...)
|
||||
void WARNING(const char *fmt, ...)
|
||||
{
|
||||
extern char *cmdname;
|
||||
va_list varg;
|
||||
@ -633,7 +633,7 @@ void bclass(int c)
|
||||
}
|
||||
}
|
||||
|
||||
double errcheck(double x, char *s)
|
||||
double errcheck(double x, const char *s)
|
||||
{
|
||||
|
||||
if (errno == EDOM) {
|
||||
@ -648,9 +648,9 @@ double errcheck(double x, char *s)
|
||||
return x;
|
||||
}
|
||||
|
||||
int isclvar(char *s) /* is s of form var=something ? */
|
||||
int isclvar(const char *s) /* is s of form var=something ? */
|
||||
{
|
||||
char *os = s;
|
||||
const char *os = s;
|
||||
|
||||
if (!isalpha((uschar) *s) && *s != '_')
|
||||
return 0;
|
||||
@ -665,7 +665,7 @@ int isclvar(char *s) /* is s of form var=something ? */
|
||||
/* wrong: violates 4.10.1.4 of ansi C standard */
|
||||
|
||||
#include <math.h>
|
||||
int is_number(char *s)
|
||||
int is_number(const char *s)
|
||||
{
|
||||
double r;
|
||||
char *ep;
|
||||
|
@ -1,6 +1,14 @@
|
||||
This file contains a make shell script and a version
|
||||
of the file missing95.c for the Mac, courtesy of
|
||||
Dan Allen.
|
||||
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:
|
||||
|
||||
|
@ -22,11 +22,12 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
****************************************************************/
|
||||
|
||||
char *version = "version 20020210";
|
||||
const char *version = "version 20021129";
|
||||
|
||||
#define DEBUG
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <locale.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
@ -52,8 +53,9 @@ int safe = 0; /* 1 => "safe" mode */
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *fs = NULL;
|
||||
const char *fs = NULL;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
cmdname = argv[0];
|
||||
if (argc == 1) {
|
||||
fprintf(stderr, "Usage: %s [-f programfile | 'program'] [-Ffieldsep] [-v var=value] [files]\n", cmdname);
|
||||
|
@ -26,6 +26,7 @@ CFLAGS = -g
|
||||
CFLAGS = -O2
|
||||
CFLAGS =
|
||||
|
||||
CC = gcc -Wall -g -Wwrite-strings
|
||||
CC = gcc -Wall -g
|
||||
CC = /opt/SUNWspro/bin/cc
|
||||
CC = /opt/pure/purify/purify cc
|
||||
@ -37,11 +38,14 @@ YFLAGS = -d
|
||||
|
||||
OFILES = b.o main.o parse.o proctab.o tran.o lib.o run.o lex.o
|
||||
|
||||
SOURCE = awk.h ytab.c ytab.h proto.h awkgram.y lex.c b.c main.c maketab.c parse.c lib.c run.c tran.c proctab.c missing95.c
|
||||
SOURCE = awk.h ytab.c ytab.h proto.h awkgram.y lex.c b.c main.c \
|
||||
maketab.c parse.c lib.c run.c tran.c proctab.c missing95.c
|
||||
|
||||
LISTING = awk.h proto.h awkgram.y lex.c b.c main.c maketab.c parse.c lib.c run.c tran.c missing95.c
|
||||
LISTING = awk.h proto.h awkgram.y lex.c b.c main.c maketab.c parse.c \
|
||||
lib.c run.c tran.c missing95.c
|
||||
|
||||
SHIP = README FIXES $(SOURCE) ytab[ch].bak makefile makefile.win buildwin.bat mac.code awk.1
|
||||
SHIP = README FIXES $(SOURCE) ytab[ch].bak makefile makefile.win \
|
||||
buildwin.bat mac.code awk.1
|
||||
|
||||
a.out: ytab.o $(OFILES)
|
||||
$(CC) $(CFLAGS) ytab.o $(OFILES) $(ALLOC) -lm
|
||||
|
@ -36,8 +36,8 @@ THIS SOFTWARE.
|
||||
|
||||
struct xx
|
||||
{ int token;
|
||||
char *name;
|
||||
char *pname;
|
||||
const char *name;
|
||||
const char *pname;
|
||||
} proc[] = {
|
||||
{ PROGRAM, "program", NULL },
|
||||
{ BOR, "boolop", " || " },
|
||||
@ -107,12 +107,12 @@ struct xx
|
||||
};
|
||||
|
||||
#define SIZE (LASTTOKEN - FIRSTTOKEN + 1)
|
||||
char *table[SIZE];
|
||||
const char *table[SIZE];
|
||||
char *names[SIZE];
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct xx *p;
|
||||
const struct xx *p;
|
||||
int i, n, tok;
|
||||
char c;
|
||||
FILE *fp;
|
||||
|
@ -253,7 +253,7 @@ void defn(Cell *v, Node *vl, Node *st) /* turn on FCN bit in definition, */
|
||||
dprintf( ("defining func %s (%d args)\n", v->nval, n) );
|
||||
}
|
||||
|
||||
int isarg(char *s) /* is s in argument list for current function? */
|
||||
int isarg(const char *s) /* is s in argument list for current function? */
|
||||
{ /* return -1 if not, otherwise arg # */
|
||||
extern Node *arglist;
|
||||
Node *p = arglist;
|
||||
|
@ -33,28 +33,28 @@ extern int yylex(void);
|
||||
extern void startreg(void);
|
||||
extern int input(void);
|
||||
extern void unput(int);
|
||||
extern void unputstr(char *);
|
||||
extern void unputstr(const char *);
|
||||
extern int yylook(void);
|
||||
extern int yyback(int *, int);
|
||||
extern int yyinput(void);
|
||||
|
||||
extern fa *makedfa(char *, int);
|
||||
extern fa *mkdfa(char *, int);
|
||||
extern fa *makedfa(const char *, int);
|
||||
extern fa *mkdfa(const char *, int);
|
||||
extern int makeinit(fa *, int);
|
||||
extern void penter(Node *);
|
||||
extern void freetr(Node *);
|
||||
extern int hexstr(char **);
|
||||
extern int quoted(char **);
|
||||
extern char *cclenter(char *);
|
||||
extern void overflo(char *);
|
||||
extern char *cclenter(const char *);
|
||||
extern void overflo(const char *);
|
||||
extern void cfoll(fa *, Node *);
|
||||
extern int first(Node *);
|
||||
extern void follow(Node *);
|
||||
extern int member(int, char *);
|
||||
extern int match(fa *, char *);
|
||||
extern int pmatch(fa *, char *);
|
||||
extern int nematch(fa *, char *);
|
||||
extern Node *reparse(char *);
|
||||
extern int member(int, const char *);
|
||||
extern int match(fa *, const char *);
|
||||
extern int pmatch(fa *, const char *);
|
||||
extern int nematch(fa *, const char *);
|
||||
extern Node *reparse(const char *);
|
||||
extern Node *regexp(void);
|
||||
extern Node *primary(void);
|
||||
extern Node *concat(Node *);
|
||||
@ -87,7 +87,7 @@ extern Node *makearr(Node *);
|
||||
extern Node *pa2stat(Node *, Node *, Node *);
|
||||
extern Node *linkum(Node *, Node *);
|
||||
extern void defn(Cell *, Node *, Node *);
|
||||
extern int isarg(char *);
|
||||
extern int isarg(const char *);
|
||||
extern char *tokname(int);
|
||||
extern Cell *(*proctab[])(Node **, int);
|
||||
extern int ptoi(void *);
|
||||
@ -98,18 +98,19 @@ extern void arginit(int, char **);
|
||||
extern void envinit(char **);
|
||||
extern Array *makesymtab(int);
|
||||
extern void freesymtab(Cell *);
|
||||
extern void freeelem(Cell *, char *);
|
||||
extern Cell *setsymtab(char *, char *, double, unsigned int, Array *);
|
||||
extern int hash(char *, int);
|
||||
extern void freeelem(Cell *, const char *);
|
||||
extern Cell *setsymtab(const char *, const char *, double, unsigned int, Array *);
|
||||
extern int hash(const char *, int);
|
||||
extern void rehash(Array *);
|
||||
extern Cell *lookup(char *, Array *);
|
||||
extern Cell *lookup(const char *, Array *);
|
||||
extern double setfval(Cell *, double);
|
||||
extern void funnyvar(Cell *, char *);
|
||||
extern char *setsval(Cell *, char *);
|
||||
extern void funnyvar(Cell *, const char *);
|
||||
extern char *setsval(Cell *, const char *);
|
||||
extern double getfval(Cell *);
|
||||
extern char *getsval(Cell *);
|
||||
extern char *tostring(char *);
|
||||
extern char *qstring(char *, int);
|
||||
extern char *getpssval(Cell *); /* for print */
|
||||
extern char *tostring(const char *);
|
||||
extern char *qstring(const char *, int);
|
||||
|
||||
extern void recinit(unsigned int);
|
||||
extern void initgetrec(void);
|
||||
@ -123,24 +124,24 @@ extern void setclvar(char *);
|
||||
extern void fldbld(void);
|
||||
extern void cleanfld(int, int);
|
||||
extern void newfld(int);
|
||||
extern int refldbld(char *, char *);
|
||||
extern int refldbld(const char *, const char *);
|
||||
extern void recbld(void);
|
||||
extern Cell *fieldadr(int);
|
||||
extern void yyerror(char *);
|
||||
extern void yyerror(const char *);
|
||||
extern void fpecatch(int);
|
||||
extern void bracecheck(void);
|
||||
extern void bcheck2(int, int, int);
|
||||
extern void SYNTAX(char *, ...);
|
||||
extern void FATAL(char *, ...);
|
||||
extern void WARNING(char *, ...);
|
||||
extern void SYNTAX(const char *, ...);
|
||||
extern void FATAL(const char *, ...);
|
||||
extern void WARNING(const char *, ...);
|
||||
extern void error(void);
|
||||
extern void eprint(void);
|
||||
extern void bclass(int);
|
||||
extern double errcheck(double, char *);
|
||||
extern int isclvar(char *);
|
||||
extern int is_number(char *);
|
||||
extern double errcheck(double, const char *);
|
||||
extern int isclvar(const char *);
|
||||
extern int is_number(const char *);
|
||||
|
||||
extern int adjbuf(char **pb, int *sz, int min, int q, char **pbp, char *what);
|
||||
extern int adjbuf(char **pb, int *sz, int min, int q, char **pbp, const char *what);
|
||||
extern void run(Node *);
|
||||
extern Cell *execute(Node *);
|
||||
extern Cell *program(Node **, int);
|
||||
@ -162,7 +163,7 @@ extern Cell *field(Node **, int);
|
||||
extern Cell *indirect(Node **, int);
|
||||
extern Cell *substr(Node **, int);
|
||||
extern Cell *sindex(Node **, int);
|
||||
extern int format(char **, int *, char *, Node *);
|
||||
extern int format(char **, int *, const char *, Node *);
|
||||
extern Cell *awksprintf(Node **, int);
|
||||
extern Cell *awkprintf(Node **, int);
|
||||
extern Cell *arith(Node **, int);
|
||||
@ -183,8 +184,8 @@ extern Cell *bltin(Node **, int);
|
||||
extern Cell *printstat(Node **, int);
|
||||
extern Cell *nullproc(Node **, int);
|
||||
extern FILE *redirect(int, Node *);
|
||||
extern FILE *openfile(int, char *);
|
||||
extern char *filename(FILE *);
|
||||
extern FILE *openfile(int, const char *);
|
||||
extern const char *filename(FILE *);
|
||||
extern Cell *closefile(Node **, int);
|
||||
extern void closeall(void);
|
||||
extern Cell *sub(Node **, int);
|
||||
|
@ -90,7 +90,7 @@ Node *curnode = NULL; /* the node being executed, for debugging */
|
||||
|
||||
/* buffer memory management */
|
||||
int adjbuf(char **pbuf, int *psiz, int minlen, int quantum, char **pbptr,
|
||||
char *whatrtn)
|
||||
const char *whatrtn)
|
||||
/* pbuf: address of pointer to buffer being managed
|
||||
* psiz: address of buffer size variable
|
||||
* minlen: minimum length of buffer needed
|
||||
@ -247,7 +247,7 @@ Cell *call(Node **a, int n) /* function call. very kludgy and fragile */
|
||||
y = execute(x);
|
||||
oargs[i] = y;
|
||||
dprintf( ("args[%d]: %s %f <%s>, t=%o\n",
|
||||
i, y->nval, y->fval, isarr(y) ? "(array)" : y->sval, y->tval) );
|
||||
i, NN(y->nval), y->fval, isarr(y) ? "(array)" : NN(y->sval), y->tval) );
|
||||
if (isfcn(y))
|
||||
FATAL("can't use function %s as argument in %s", y->nval, s);
|
||||
if (isarr(y))
|
||||
@ -463,7 +463,7 @@ Cell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */
|
||||
tempfree(y);
|
||||
}
|
||||
if (!isarr(x)) {
|
||||
dprintf( ("making %s into an array\n", x->nval) );
|
||||
dprintf( ("making %s into an array\n", NN(x->nval)) );
|
||||
if (freeable(x))
|
||||
xfree(x->sval);
|
||||
x->tval &= ~(STR|NUM|DONTFREE);
|
||||
@ -564,7 +564,7 @@ Cell *matchop(Node **a, int n) /* ~ and match() */
|
||||
char *s, *t;
|
||||
int i;
|
||||
fa *pfa;
|
||||
int (*mf)(fa *, char *) = match, mode = 0;
|
||||
int (*mf)(fa *, const char *) = match, mode = 0;
|
||||
|
||||
if (n == MATCHFCN) {
|
||||
mf = pmatch;
|
||||
@ -669,7 +669,7 @@ Cell *relop(Node **a, int n) /* a[0 < a[1], etc. */
|
||||
void tfree(Cell *a) /* free a tempcell */
|
||||
{
|
||||
if (freeable(a)) {
|
||||
dprintf( ("freeing %s %s %o\n", a->nval, a->sval, a->tval) );
|
||||
dprintf( ("freeing %s %s %o\n", NN(a->nval), NN(a->sval), a->tval) );
|
||||
xfree(a->sval);
|
||||
}
|
||||
if (a == tmps)
|
||||
@ -790,10 +790,11 @@ Cell *sindex(Node **a, int nnn) /* index(a[0], a[1]) */
|
||||
|
||||
#define MAXNUMSIZE 50
|
||||
|
||||
int format(char **pbuf, int *pbufsize, char *s, Node *a) /* printf-like conversions */
|
||||
int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like conversions */
|
||||
{
|
||||
char *fmt;
|
||||
char *p, *t, *os;
|
||||
char *p, *t;
|
||||
const char *os;
|
||||
Cell *x;
|
||||
int flag = 0, n;
|
||||
int fmtwd; /* format width */
|
||||
@ -844,27 +845,27 @@ int format(char **pbuf, int *pbufsize, char *s, Node *a) /* printf-like conversi
|
||||
|
||||
switch (*s) {
|
||||
case 'f': case 'e': case 'g': case 'E': case 'G':
|
||||
flag = 1;
|
||||
flag = 'f';
|
||||
break;
|
||||
case 'd': case 'i':
|
||||
flag = 2;
|
||||
flag = 'd';
|
||||
if(*(s-1) == 'l') break;
|
||||
*(t-1) = 'l';
|
||||
*t = 'd';
|
||||
*++t = '\0';
|
||||
break;
|
||||
case 'o': case 'x': case 'X': case 'u':
|
||||
flag = *(s-1) == 'l' ? 2 : 3;
|
||||
flag = *(s-1) == 'l' ? 'd' : 'u';
|
||||
break;
|
||||
case 's':
|
||||
flag = 4;
|
||||
flag = 's';
|
||||
break;
|
||||
case 'c':
|
||||
flag = 5;
|
||||
flag = 'c';
|
||||
break;
|
||||
default:
|
||||
WARNING("weird printf conversion %s", fmt);
|
||||
flag = 0;
|
||||
flag = '?';
|
||||
break;
|
||||
}
|
||||
if (a == NULL)
|
||||
@ -876,7 +877,7 @@ int format(char **pbuf, int *pbufsize, char *s, Node *a) /* printf-like conversi
|
||||
n = fmtwd;
|
||||
adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format");
|
||||
switch (flag) {
|
||||
case 0: sprintf(p, "%s", fmt); /* unknown, so dump it too */
|
||||
case '?': sprintf(p, "%s", fmt); /* unknown, so dump it too */
|
||||
t = getsval(x);
|
||||
n = strlen(t);
|
||||
if (fmtwd > n)
|
||||
@ -885,10 +886,10 @@ int format(char **pbuf, int *pbufsize, char *s, Node *a) /* printf-like conversi
|
||||
p += strlen(p);
|
||||
sprintf(p, "%s", t);
|
||||
break;
|
||||
case 1: sprintf(p, fmt, getfval(x)); break;
|
||||
case 2: sprintf(p, fmt, (long) getfval(x)); break;
|
||||
case 3: sprintf(p, fmt, (int) getfval(x)); break;
|
||||
case 4:
|
||||
case 'f': sprintf(p, fmt, getfval(x)); break;
|
||||
case 'd': sprintf(p, fmt, (long) getfval(x)); break;
|
||||
case 'u': sprintf(p, fmt, (int) getfval(x)); break;
|
||||
case 's':
|
||||
t = getsval(x);
|
||||
n = strlen(t);
|
||||
if (fmtwd > n)
|
||||
@ -897,15 +898,19 @@ int format(char **pbuf, int *pbufsize, char *s, Node *a) /* printf-like conversi
|
||||
FATAL("huge string/format (%d chars) in printf %.30s... ran format() out of memory", n, t);
|
||||
sprintf(p, fmt, t);
|
||||
break;
|
||||
case 5:
|
||||
case 'c':
|
||||
if (isnum(x)) {
|
||||
if (getfval(x))
|
||||
sprintf(p, fmt, (int) getfval(x));
|
||||
else
|
||||
*p++ = '\0';
|
||||
else {
|
||||
*p++ = '\0'; /* explicit null byte */
|
||||
*p = '\0'; /* next output will start here */
|
||||
}
|
||||
} else
|
||||
sprintf(p, fmt, getsval(x)[0]);
|
||||
break;
|
||||
default:
|
||||
FATAL("can't happen: bad conversion %c in format()", flag);
|
||||
}
|
||||
tempfree(x);
|
||||
p += strlen(p);
|
||||
@ -1210,7 +1215,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
|
||||
sep = *fs;
|
||||
ap = execute(a[1]); /* array name */
|
||||
freesymtab(ap);
|
||||
dprintf( ("split: s=|%s|, a=%s, sep=|%s|\n", s, ap->nval, fs) );
|
||||
dprintf( ("split: s=|%s|, a=%s, sep=|%s|\n", s, NN(ap->nval), fs) );
|
||||
ap->tval &= ~STR;
|
||||
ap->tval |= ARR;
|
||||
ap->sval = (char *) makesymtab(NSYMTAB);
|
||||
@ -1504,11 +1509,11 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis
|
||||
if (t == FTOUPPER) {
|
||||
for (p = buf; *p; p++)
|
||||
if (islower((uschar) *p))
|
||||
*p = toupper(*p);
|
||||
*p = toupper((uschar)*p);
|
||||
} else {
|
||||
for (p = buf; *p; p++)
|
||||
if (isupper((uschar) *p))
|
||||
*p = tolower(*p);
|
||||
*p = tolower((uschar)*p);
|
||||
}
|
||||
tempfree(x);
|
||||
x = gettemp();
|
||||
@ -1551,7 +1556,7 @@ Cell *printstat(Node **a, int n) /* print a[0] */
|
||||
fp = redirect(ptoi(a[1]), a[2]);
|
||||
for (x = a[0]; x != NULL; x = x->nnext) {
|
||||
y = execute(x);
|
||||
fputs(getsval(y), fp);
|
||||
fputs(getpssval(y), fp);
|
||||
tempfree(y);
|
||||
if (x->nnext == NULL)
|
||||
fputs(*ORS, fp);
|
||||
@ -1590,7 +1595,7 @@ FILE *redirect(int a, Node *b) /* set up all i/o redirections */
|
||||
|
||||
struct files {
|
||||
FILE *fp;
|
||||
char *fname;
|
||||
const char *fname;
|
||||
int mode; /* '|', 'a', 'w' => LE/LT, GT */
|
||||
} files[FOPEN_MAX] ={
|
||||
{ NULL, "/dev/stdin", LT }, /* watch out: don't free this! */
|
||||
@ -1605,9 +1610,9 @@ void stdinit(void) /* in case stdin, etc., are not constants */
|
||||
files[2].fp = stderr;
|
||||
}
|
||||
|
||||
FILE *openfile(int a, char *us)
|
||||
FILE *openfile(int a, const char *us)
|
||||
{
|
||||
char *s = us;
|
||||
const char *s = us;
|
||||
int i, m;
|
||||
FILE *fp = 0;
|
||||
|
||||
@ -1651,7 +1656,7 @@ FILE *openfile(int a, char *us)
|
||||
return fp;
|
||||
}
|
||||
|
||||
char *filename(FILE *fp)
|
||||
const char *filename(FILE *fp)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -180,7 +180,7 @@ void freesymtab(Cell *ap) /* free a symbol table */
|
||||
free(tp);
|
||||
}
|
||||
|
||||
void freeelem(Cell *ap, char *s) /* free elem s from ap (i.e., ap["s"] */
|
||||
void freeelem(Cell *ap, const char *s) /* free elem s from ap (i.e., ap["s"] */
|
||||
{
|
||||
Array *tp;
|
||||
Cell *p, *prev = NULL;
|
||||
@ -203,14 +203,14 @@ void freeelem(Cell *ap, char *s) /* free elem s from ap (i.e., ap["s"] */
|
||||
}
|
||||
}
|
||||
|
||||
Cell *setsymtab(char *n, char *s, Awkfloat f, unsigned t, Array *tp)
|
||||
Cell *setsymtab(const char *n, const char *s, Awkfloat f, unsigned t, Array *tp)
|
||||
{
|
||||
int h;
|
||||
Cell *p;
|
||||
|
||||
if (n != NULL && (p = lookup(n, tp)) != NULL) {
|
||||
dprintf( ("setsymtab found %p: n=%s s=\"%s\" f=%g t=%o\n",
|
||||
p, p->nval, p->sval, p->fval, p->tval) );
|
||||
p, NN(p->nval), NN(p->sval), p->fval, p->tval) );
|
||||
return(p);
|
||||
}
|
||||
p = (Cell *) malloc(sizeof(Cell));
|
||||
@ -233,7 +233,7 @@ Cell *setsymtab(char *n, char *s, Awkfloat f, unsigned t, Array *tp)
|
||||
return(p);
|
||||
}
|
||||
|
||||
int hash(char *s, int n) /* form hash value for string s */
|
||||
int hash(const char *s, int n) /* form hash value for string s */
|
||||
{
|
||||
unsigned hashval;
|
||||
|
||||
@ -264,7 +264,7 @@ void rehash(Array *tp) /* rehash items in small table into big one */
|
||||
tp->size = nsz;
|
||||
}
|
||||
|
||||
Cell *lookup(char *s, Array *tp) /* look for s in tp */
|
||||
Cell *lookup(const char *s, Array *tp) /* look for s in tp */
|
||||
{
|
||||
Cell *p;
|
||||
int h;
|
||||
@ -296,11 +296,11 @@ Awkfloat setfval(Cell *vp, Awkfloat f) /* set float val of a Cell */
|
||||
xfree(vp->sval); /* free any previous string */
|
||||
vp->tval &= ~STR; /* mark string invalid */
|
||||
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, NN(vp->nval), f, vp->tval) );
|
||||
return vp->fval = f;
|
||||
}
|
||||
|
||||
void funnyvar(Cell *vp, char *rw)
|
||||
void funnyvar(Cell *vp, const char *rw)
|
||||
{
|
||||
if (isarr(vp))
|
||||
FATAL("can't %s %s; it's an array name.", rw, vp->nval);
|
||||
@ -310,12 +310,12 @@ void funnyvar(Cell *vp, char *rw)
|
||||
vp, vp->nval, vp->sval, vp->fval, vp->tval);
|
||||
}
|
||||
|
||||
char *setsval(Cell *vp, char *s) /* set string val of a Cell */
|
||||
char *setsval(Cell *vp, const char *s) /* set string val of a Cell */
|
||||
{
|
||||
char *t;
|
||||
int fldno;
|
||||
|
||||
dprintf( ("starting setsval %p: %s = \"%s\", t=%o\n", vp, vp->nval, s, vp->tval) );
|
||||
dprintf( ("starting setsval %p: %s = \"%s\", t=%o\n", vp, NN(vp->nval), s, vp->tval) );
|
||||
if ((vp->tval & (NUM | STR)) == 0)
|
||||
funnyvar(vp, "assign to");
|
||||
if (isfld(vp)) {
|
||||
@ -334,7 +334,7 @@ char *setsval(Cell *vp, char *s) /* set string val of a Cell */
|
||||
if (freeable(vp))
|
||||
xfree(vp->sval);
|
||||
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, NN(vp->nval), t,t, vp->tval) );
|
||||
return(vp->sval = t);
|
||||
}
|
||||
|
||||
@ -351,11 +351,12 @@ Awkfloat getfval(Cell *vp) /* get float val of a Cell */
|
||||
if (is_number(vp->sval) && !(vp->tval&CON))
|
||||
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, NN(vp->nval), vp->fval, vp->tval) );
|
||||
return(vp->fval);
|
||||
}
|
||||
|
||||
char *getsval(Cell *vp) /* get string val of a Cell */
|
||||
static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cell */
|
||||
|
||||
{
|
||||
char s[100]; /* BUG: unchecked */
|
||||
double dtemp;
|
||||
@ -372,16 +373,27 @@ char *getsval(Cell *vp) /* get string val of a Cell */
|
||||
if (modf(vp->fval, &dtemp) == 0) /* it's integral */
|
||||
sprintf(s, "%.30g", vp->fval);
|
||||
else
|
||||
sprintf(s, *CONVFMT, vp->fval);
|
||||
sprintf(s, *fmt, vp->fval);
|
||||
vp->sval = tostring(s);
|
||||
vp->tval &= ~DONTFREE;
|
||||
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, NN(vp->nval), vp->sval, vp->sval, vp->tval) );
|
||||
return(vp->sval);
|
||||
}
|
||||
|
||||
char *tostring(char *s) /* make a copy of string s */
|
||||
char *getsval(Cell *vp) /* get string val of a Cell */
|
||||
{
|
||||
return get_str_val(vp, CONVFMT);
|
||||
}
|
||||
|
||||
char *getpssval(Cell *vp) /* get string val of a Cell for print */
|
||||
{
|
||||
return get_str_val(vp, OFMT);
|
||||
}
|
||||
|
||||
|
||||
char *tostring(const char *s) /* make a copy of string s */
|
||||
{
|
||||
char *p;
|
||||
|
||||
@ -392,9 +404,9 @@ char *tostring(char *s) /* make a copy of string s */
|
||||
return(p);
|
||||
}
|
||||
|
||||
char *qstring(char *is, int delim) /* collect string up to next delim */
|
||||
char *qstring(const char *is, int delim) /* collect string up to next delim */
|
||||
{
|
||||
char *os = is;
|
||||
const char *os = is;
|
||||
int c, n;
|
||||
uschar *s = (uschar *) is;
|
||||
uschar *buf, *bp;
|
||||
|
Loading…
Reference in New Issue
Block a user