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:
David E. O'Brien 2002-12-13 04:59:48 +00:00
parent 146a1e500c
commit 813da98d0e
14 changed files with 246 additions and 143 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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 */

View File

@ -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') {

View File

@ -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;

View File

@ -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;

View File

@ -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:

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;