Remove obsolete implementation of awk.

This commit is contained in:
Kees van Reeuwijk
2010-04-22 13:41:35 +00:00
parent d106968d77
commit 55129194a3
14 changed files with 0 additions and 5761 deletions

View File

@@ -1,30 +0,0 @@
# Makefile for awk.
CC = exec cc
CFLAGS = -D_MINIX -D_POSIX_SOURCE -wo -w
LDFLAGS = -i -f
OBJS = m.o e.o n.o l.o r.o v.o y.o regexp.o k.o
all: awk.old
awk.old: $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS) #-lm
install -S 32kw $@
install: /usr/bin/awk.old
/usr/bin/awk.old: awk.old
install -cs -o bin $? $@
clean:
rm -f awk awk.old *.o a.out *.bak core
e.o: awk.h regexp.h
l.o: awk.h
m.o: awk.h
n.o: awk.h
r.o: awk.h regexp.h
regexp.o: regexp.h
v.o: awk.h regexp.h
y.o: awk.h

View File

@@ -1,13 +0,0 @@
A small AWK clone for the 16-bit Minix
We have written this program for the Minix 1.2 to fit into 64K+64K
memory. When compiling this program, you need the Peter S. Housel's
Floating Math Package with corrected the atan() function. Original atan()
function has incorrect argument sequence.
This program supports Japanese Shift-JIS KANJI code and passes
all the test program of the "AWK programming language" written by original
AWK authors except some programs relied upon the way of regular expression
evaluation.
Kouichi Hirabayashi (kh@mogami-wire.co.jp)

View File

@@ -1,186 +0,0 @@
/*
* a small awk clone
*
* (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi
*
* Absolutely no warranty. Use this software with your own risk.
*
* Permission to use, copy, modify and distribute this software for any
* purpose and without fee is hereby granted, provided that the above
* copyright and disclaimer notice.
*
* This program was written to fit into 64K+64K memory of the Minix 1.2.
*/
/* lexical/parser tokens and executable statements */
#define FIRSTP 256
#define ARG 256
#define ARITH 257
#define ARRAY 258
#define ASSIGN 259
#define CALL 260
#define CAT 261
#define COND 262
#define DELETE 263
#define DO 264
#define ELEMENT 265
#define FIELD 266
#define FOR 267
#define FORIN 268
#define GETLINE 269
#define IF 270
#define IN 271
#define JUMP 272
#define MATHFUN 273
#define NULPROC 274
#define P1STAT 275
#define P2STAT 276
#define PRINT 277
#define PRINT0 278
#define STRFUN 279
#define SUBST 280
#define USRFUN 281
#define WHILE 282
#define LASTP 282
/* lexical token */
#define ADD 300 /* + */
#define ADDEQ 301 /* += */
#define AND 302 /* && */
#define BEGIN 303 /* BEGIN */
#define BINAND 304 /* & */
#define BINOR 305 /* | */
#define BREAK 306 /* break */
#define CLOSE 307 /* close */
#define CONTIN 308 /* continue */
#define DEC 309 /* -- */
#define DIV 310 /* / */
#define DIVEQ 311 /* /= */
#define ELSE 312 /* else */
#define END 313 /* END */
#define EOL 314 /* ; or '\n' */
#define EQ 315 /* == */
#define EXIT 316 /* exit */
#define FUNC 317 /* function */
#define GE 318 /* >= */
#define GT 319 /* > */
#define IDENT 320 /* identifier */
#define INC 321 /* ++ */
#define LE 322 /* <= */
#define LT 323 /* < */
#define MATCH 324 /* ~ */
#define MOD 325 /* % */
#define MODEQ 326 /* %= */
#define MULT 327 /* * */
#define MULTEQ 328 /* *= */
#define NE 329 /* != */
#define NEXT 330 /* next */
#define NOMATCH 331 /* !~ */
#define NOT 332 /* ! */
#define NUMBER 333 /* integer or floating number */
#define OR 334 /* || */
#define POWEQ 335 /* ^= */
#define POWER 336 /* ^ */
#define PRINTF 337 /* printf */
#define REGEXP 338 /* /REG/ */
#define RETURN 339 /* return */
#define SHIFTL 340 /* << */
#define SHIFTR 341 /* >> */
#define SPRINT 342 /* sprint */
#define SPRINTF 343 /* sprintf */
#define STRING 344 /* ".." */
#define SUB 345 /* - */
#define SUBEQ 346 /* -= */
#define SYSTEM 347 /* system */
#define UMINUS 348 /* - */
/* tokens in parser */
#define VALUE 400 /* value node */
#define INCDEC 401 /* ++, -- */
#define PRE 402 /* pre incre/decre */
#define POST 403 /* post incre/decre */
/* redirect in print(f) statement */
#define R_OUT 410 /* > */
#define R_APD 411 /* >> */
#define R_PIPE 412 /* | */
#define R_IN 413 /* < */
#define R_PIN 414 /* | getline */
#define R_POUT 415 /* print | */
/* function */
#define ATAN2 500 /* atan2 */
#define COS 501 /* cos */
#define EXP 502 /* exp */
#define INDEX 503 /* index */
#define INT 504 /* int */
#define LENGTH 505 /* length */
#define LOG 506 /* log */
#define RAND 507 /* rand */
#define RGSUB 508 /* gsub */
#define RMATCH 509 /* match */
#define RSUB 510 /* sub */
#define SIN 511 /* sin */
#define SPLIT 512 /* split */
#define SQRT 513 /* sqrt */
#define SRAND 514 /* srand */
#define SUBSTR 515 /* substr */
/* print(f) options */
#define FORMAT 1024 /* PRINTF, SPRINTF */
#define STROUT 2048 /* SPRINTF */
#define PRMASK 0x3ff /* ~(FORMAT|STROUT) */
/* node - used in parsed tree */
struct node {
int n_type; /* node type */
struct node *n_next; /* pointer to next node */
struct node *n_arg[1]; /* argument (variable length) */
};
typedef struct node NODE;
/* object cell */
struct cell {
int c_type; /* cell type */
char *c_sval; /* string value */
double c_fval; /* floating value */
};
typedef struct cell CELL;
/* cell type */
#define UDF 0 /* pass parameter */
#define VAR 1 /* variable */
#define NUM 2 /* number */
#define ARR 4 /* array */
#define STR 8 /* string */
#define REC 16 /* record */
#define FLD 32 /* filed */
#define PAT 64 /* pattern (compiled REGEXPR) */
#define BRK 128 /* break */
#define CNT 256 /* continue */
#define NXT 512 /* next */
#define EXT 1024 /* exit */
#define RTN 2048 /* return */
#define TMP 4096 /* temp cell */
#define POS 8192 /* argument position */
#define FUN 16384 /* function */
/* symbol cell - linked to symbol table */
struct symbol {
char *s_name;
CELL *s_val;
struct symbol *s_next;
};
typedef struct symbol SYMBOL;

View File

@@ -1,3 +0,0 @@
#!/bin/sh
make clean
make && make install

View File

@@ -1,952 +0,0 @@
/*
* a small awk clone
*
* (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi
*
* Absolutely no warranty. Use this software with your own risk.
*
* Permission to use, copy, modify and distribute this software for any
* purpose and without fee is hereby granted, provided that the above
* copyright and disclaimer notice.
*
* This program was written to fit into 64K+64K memory of the Minix 1.2.
*/
#include <stdio.h>
#include <ctype.h>
#include "awk.h"
#include "regexp.h"
extern char **FS, **OFS, **ORS, **OFMT;
extern double *RSTART, *RLENGTH;
extern char record[];
extern CELL *field[];
extern int r_start, r_length;
double getfval(), atof();
char *strsave(), *getsval(), *strcat(), *strstr();
CELL *mkcell(), *mktmp();
CELL *Field(), *Split(), *Forin();
CELL *Arith(), *Assign(), *Stat(), *Mathfun(), *Strfun(), *Cond();
CELL *Print(), *Cat(), *Array(), *Element();
CELL *If(), *While(), *For(), *Do(), *Jump();
CELL *P1stat(), *P2stat(), *Print0();
CELL *Arg(), *Call(), *Ret();
CELL *Subst(), *In(), *Getline(), *Delete(), *Close();
CELL *Nulproc(), *Usrfun();
CELL *_Arg();
FILE *getfp(); /* r.c */
CELL truecell = { NUM, NULL, 1.0 };
CELL falsecell = { NUM, NULL, 0.0 };
static CELL breakcell = { BRK, NULL, 0.0 };
static CELL contcell = { CNT, NULL, 0.0 };
static CELL nextcell = { NXT, NULL, 0.0 };
static CELL retcell = { RTN, NULL, 0.0 };
static CELL *retval; /* function return value */
int pateval; /* used in P1STAT & P2STAT */
static char *r_str; /* STR in 'str ~ STR */
static regexp *r_pat; /* compiled pattern for STR */
CELL *(*proctab[])() = {
Arg, Arith, Array, Assign, Call, Cat, Cond, Delete, Do, Element,
Field, For, Forin, Getline, If, In, Jump, Mathfun, Nulproc, P1stat,
P2stat, Print, Print0, Strfun, Subst, Usrfun, While
};
CELL *
execute(p) NODE *p;
{
int type, i;
CELL *r, *(*proc)();
type = p->n_type;
if (type == VALUE) {
if ((r = (CELL *) p->n_arg[0])->c_type & PAT && pateval) {
i = match(r->c_sval, (char *)record) ? 1 : 0;
r = mktmp(NUM, NULL, (double) i);
}
return r;
}
for ( ; p != NULL; p = p->n_next) {
#if 0
if (p->n_type == VALUE) continue; /* neglect */
#endif
/*
switch ((int) p->n_type) {
case ARRAY:
r = Array(p);
break;
case ARITH:
r = Arith(p);
break;
case ASSIGN:
r = Assign(p);
break;
case PRINT:
r = Print(p);
break;
case PRINT0:
r = Print0(p);
break;
case CAT:
r = Cat(p);
break;
case MATHFUN:
r = Mathfun(p);
break;
case STRFUN:
r = Strfun(p);
break;
case COND:
r = Cond(p);
break;
case IF:
r = If(p);
break;
case P1STAT:
r = P1stat(p);
break;
case P2STAT:
r = P2stat(p);
break;
case WHILE:
r = While(p);
break;
case DO:
r = Do(p);
break;
case FOR:
r = For(p);
break;
case FORIN:
r = Forin(p);
break;
case FIELD:
r = Field(p);
break;
case JUMP:
r = Jump(p);
break;
case ARG:
r = Arg(p);
break;
case CALL:
r = Call(p);
break;
case SUBST:
r = Subst(p);
break;
case ELEMENT:
r = Element(p);
break;
case IN:
r = In(p);
break;
case GETLINE:
r = Getline(p);
break;
case DELETE:
r = Delete(p);
break;
case NULPROC:
r = &truecell;
break;
default:
printf("PROGRAM ERROR ? ILLEGAL NODE TYPE(%d)\n", type);
exit(1);
break;
}
*/
i = (int) p->n_type;
if (i < FIRSTP || i > LASTP)
error("ILLEGAL PROC (%d)", i);
proc = proctab[i - FIRSTP];
r = (*proc)(p);
if (r->c_type & (BRK|CNT|NXT|RTN))
return r;
if (p->n_next != NULL)
c_free(r);
#ifdef DOS
kbhit(); /* needs in MS-DOS */
#endif
}
return r;
}
static CELL *
Arith(p) NODE *p;
{
int op;
CELL *r, *u, *v, *execute();
double x, y, fmod(), pow();
op = (int) p->n_arg[0];
if (op == UMINUS) {
u = execute(p->n_arg[1]);
x = - getfval(u);
}
else if (op == INCDEC) {
u = execute(p->n_arg[1]);
x = getfval(u);
setfval(u, x + (int) p->n_arg[2]);
if ((int) p->n_arg[3] == PRE)
return u;
/* return dummy */
}
else {
u = execute(p->n_arg[1]);
v = execute(p->n_arg[2]);
x = getfval(u);
y = getfval(v);
if (op == DIV || op == MOD) {
if (y == 0.0)
fprintf(stderr, "divid by 0\n");
}
switch (op) {
case SUB: x -= y;break;
case ADD: x += y; break;
case MULT: x *= y; break;
case DIV:
if (y == 0.0)
error("division by zero in \"/\"", (char *)0);
x /= y; break;
case MOD:
if (y == 0.0)
error("division by zero in \"%%\"", (char *)0);
x = fmod(x, y); break;
case POWER: x = pow(x, y); break;
default: printf("UNSUPPORTED ARITH OPERATOR !\n"); break;
}
c_free(v);
}
c_free(u);
r = mktmp(NUM, NULL, x);
return r;
}
static CELL *
Assign(p) NODE *p;
{
CELL *u, *v, *execute();
int op;
double x, y, fmod(), pow();
op = (int) p->n_arg[0];
u = execute(p->n_arg[1]);
#if 0
if (u->c_type == UDF) /* fix up local var */
u->c_type |= VAR|STR;
#endif
if (!(u->c_type & (VAR|FLD|REC)) && (u->c_type != UDF))
fprintf(stderr, "ASSIGN TO NON VARIABLE (%d)\n", u->c_type);
v = execute(p->n_arg[2]);
if (u == v)
goto rtn; /* same node */
if (op == ASSIGN) {
if (v->c_type & NUM/* || isnum(v->c_sval)*/)
setfval(u, getfval(v));
else
setsval(u, getsval(v));
}
else {
x = getfval(u);
y = getfval(v);
switch (op) {
case ADDEQ: x += y; break;
case SUBEQ: x -= y; break;
case MULTEQ: x *= y; break;
case DIVEQ:
if (y == 0.0)
error("division by zero in \"/=\"", (char *)0);
x /= y; break;
case MODEQ:
if (y == 0.0)
error("division by zero in \"%=\"", (char *)0);
x = fmod(x, y); break;
case POWEQ: x = pow(x, y); break;
default:
synerr("illegal assign op (%d)", op);
break;
}
setfval(u, x);
}
rtn:
c_free(v);
return u;
}
static CELL *
Cat(p) NODE *p;
{
CELL *u;
char *s, *t, str[BUFSIZ];
u = execute(p->n_arg[0]);
s = getsval(u);
for (t = str; *s; )
*t++ = *s++;
c_free(u);
u = execute(p->n_arg[1]);
s = getsval(u);
while (*s)
*t++ = *s++;
c_free(u);
*t = '\0';
return mktmp(STR, str, 0.0);
}
static CELL *
Print(p) NODE *p;
{
register int i, redir, typ;
CELL *u;
char *s, str[BUFSIZ];
char *file;
FILE *fp;
redir = (int) p->n_arg[0];
if (typ = redir & PRMASK) { /* redirect */
u = execute(p->n_arg[1]);
file = getsval(u);
if (typ == R_PIPE)
typ = R_POUT;
fp = getfp(file, typ);
c_free(u);
}
else
fp = stdout;
if (redir & FORMAT) /* format */
format(str, p);
else {
*str = '\0';
for (i = 2; p->n_arg[i] != NULL; i++) {
if (i > 2)
strcat(str, *OFS);
u = execute(p->n_arg[i]);
s = getsval(u);
strcat(str, s);
c_free(u);
}
strcat(str, *ORS);
}
if (redir & STROUT) /* sprintf */
return mktmp(STR, str, 0.0);
fputs(str, fp);
fflush(fp);
return &truecell;
}
static CELL *
Mathfun(p) NODE *p;
{
CELL *u, *v;
double x, y;
double atan2(), cos(), exp(), log(), sin(), sqrt(), modf();
if ((int) p->n_arg[1] == 0) {
u = NULL;
x = 0.0;
}
else {
u = execute(p->n_arg[2]);
x = getfval(u);
}
switch ((int) p->n_arg[0]) {
case ATAN2:
if ((int) p->n_arg[1] == 2) {
v = execute(p->n_arg[3]);
y = getfval(v);
x = atan2(x, y);
c_free(v);
}
else
x = 0.0;
break;
case COS: x = cos(x); break;
case EXP: x = exp(x); break;
case INT: y = modf(x, &x); break;
case LOG: x = log(x); break;
case SIN: x = sin(x); break;
case SQRT: x = sqrt(x); break;
case RAND: x = (double) rand() / 32768.0; break;
case SRAND: if (x == 0.0)
x = (double) time(0);
x = (double) srand((int) x);
break;
default:
fprintf(stderr, "unknown math function (%d)\n", p->n_arg[2]);
break;
}
if (u != NULL)
c_free(u);
return mktmp(NUM, NULL, x);
}
static CELL *
Strfun(p) NODE *p;
{
CELL *u, *v, *r;
char *s, *t, str[BUFSIZ];
int i, m, n;
double x;
regexp *pat, *getpat();
n = (int) p->n_arg[1];
if (n > 0 && (int) p->n_arg[0] != SPLIT) {
u = execute(p->n_arg[2]);
s = getsval(u);
}
else {
s = "";
u = NULL;
}
switch ((int) p->n_arg[0]) {
case INDEX:
if (n > 1) {
v = execute(p->n_arg[3]);
t = getsval(v);
i = Index(s, t);
c_free(v);
}
else
i = 0;
r = mktmp(NUM, NULL, (double) i);
break;
case LENGTH:
i = (n > 0) ? jstrlen(s) : jstrlen(record);
r = mktmp(NUM, NULL, (double) i);
break;
case SPLIT:
r = Split(p);
break;
case SUBSTR:
if (n > 1) {
v = execute(p->n_arg[3]);
m = (int) getfval(v) - 1;
c_free(v);
}
else
m = 0;
if (n > 2) {
v = execute(p->n_arg[4]);
n = (int) getfval(v);
c_free(v);
}
else
n = jstrlen(s) - m;
for (t = str; *s && m-- > 0; s++)
if (isKanji(*s))
s++;
while (*s && n-- > 0) {
if (isKanji(*s))
*t++ = *s++;
*t++ = *s++;
}
*t = '\0';
r = mktmp(STR, str, 0.0);
break;
case RMATCH:
if (n > 1) {
v = execute(p->n_arg[3]);
pat = getpat(v);
match(pat, s);
c_free(v);
if (r_start) { /* change only if match */
*RSTART = (double) r_start;
*RLENGTH = (double) r_length;
}
r = mktmp(NUM, NULL, (double) r_start);
}
else
error("missing regexpr in match(str, regexpr)");
break;
case CLOSE:
r = Close(s);
break;
case SYSTEM:
r = mktmp(NUM, NULL, system(s) == -1 ? 0.0 : 1.0);
break;
default:
fprintf(stderr, "unknown string function");
break;
}
c_free(u);
return r;
}
static regexp *
getpat(r) CELL *r;
{
regexp *pat, *mkpat();
if (r->c_type & PAT)
pat = (regexp *) r->c_sval;
else {
if (r_str && strcmp(r_str, r->c_sval) == 0)
pat = r_pat;
else {
sfree(r_str); sfree(r_pat);
r_str = strsave(getsval(r));
pat = r_pat = mkpat(r_str);
}
}
return pat;
}
static CELL *
Subst(p) NODE *p;
{
CELL *u, *v, *w;
char *s, *t, *r, str[BUFSIZ], *strcpy();
int i, n;
n = (int) p->n_arg[1];
if (n > 1) {
u = execute(p->n_arg[3]); /* substitute string */
s = getsval(u);
v = execute(p->n_arg[2]); /* expr */
if (n > 2) {
w = execute(p->n_arg[4]);
t = getsval(w);
r = str;
}
else {
t = r = record;
w = NULL;
}
i = (int) p->n_arg[0] == RGSUB ? 0 : 1;
if (v->c_type & (PAT|STR))
i = Sub(r, v->c_sval, (v->c_type & STR), s, t, i);
else
error("[g]sub(PAT, .. ) must be /../ or string (%d)",
w->c_type);
if (n > 2) {
if (w->c_type & REC) {
strcpy(record, str);
mkfld(record, *FS, field);
}
else
setsval(w, str);
}
else
mkfld(record, *FS, field);
c_free(u);
c_free(v);
c_free(w);
}
else
i = 0;
return mktmp(NUM, NULL, (double) i);
}
static CELL *
Cond(p) NODE *p;
{
CELL *u, *v;
double x, y;
int op, i, j;
char *s;
int save = pateval;
op = (int) p->n_arg[0];
u = execute(p->n_arg[1]);
x = getfval(u);
/*
printf("Cond(%d)(%s)\n", u->c_type, u->c_sval);
*/
if (op == AND || op == OR || op == NOT) {
if (u->c_type & NUM)
i = (x != 0.0);
else {
s = getsval(u);
i = (s != (char *)NULL) && (*s != '\0');
}
}
if (op == AND && !i) {
c_free(u);
return &falsecell;
}
if (op == OR && i) {
c_free(u);
return &truecell;
}
if (op == NOT)
i = i == 0 ? 1 : 0;
else {
if (op == MATCH || op == NOMATCH)
pateval = 0;
v = execute(p->n_arg[2]);
y = getfval(v);
if (op == AND || op == OR || op == BINAND || op == BINOR) {
if (v->c_type & NUM)
j = (y != 0.0);
else {
s = getsval(v);
j = (s != (char *)NULL) && (*s != '\0');
}
switch (op) {
case AND: i = i && j; break;
case OR: i = i || j; break;
case BINAND: i = i & j; break;
case BINOR: i = i | j; break;
}
}
else if (op == MATCH || op == NOMATCH) {
char *s;
regexp *pat, *getpat();
s = getsval(u);
pat = getpat(v);
i = match(pat, s) == 0 ? 0 : 1;
if (op == NOMATCH)
i = i == 0 ? 1 : 0;
}
else { /* relative operator */
/*
printf("Cond(%d)(%d)(%s)(%s)\n", u->c_type, v->c_type, u->c_sval, v->c_sval);
*/
if ((u->c_type & NUM) && (v->c_type & NUM))
i = x < y ? -1 : (x > y ? 1 : 0);
else
i = strcmp(getsval(u), getsval(v));
/*
printf("Cond(%d)(%d)(%g)(%g)(%d)\n", u->c_type, v->c_type, x, y, i);
*/
switch (op) {
case LT: i = i < 0 ? 1 : 0; break;
case LE: i = i <= 0 ? 1 : 0; break;
case EQ: i = i == 0 ? 1 : 0; break;
case NE: i = i != 0 ? 1 : 0; break;
case GT: i = i > 0 ? 1 : 0; break;
case GE: i = i >= 0 ? 1 : 0; break;
default:
fprintf(stderr, "unknown relative operator (%d)\n", op);
break;
}
}
c_free(v);
}
c_free(u);
pateval = save;
return mktmp(NUM, NULL, (double) i);
}
static CELL *
If(p) NODE *p;
{
CELL *u;
int i;
char *s;
u = execute(p->n_arg[0]);
if (u->c_type & NUM)
i = (getfval(u) != 0.0);
else {
s = getsval(u);
i = (s != (char *)NULL) && (*s != '\0');
}
c_free(u);
if (i)
u = execute(p->n_arg[1]);
else if (p->n_arg[2])
u = execute(p->n_arg[2]);
else
u = &truecell;
return u;
}
static CELL *
While(p) NODE *p;
{
CELL *u;
double x;
for (;;) {
u = execute(p->n_arg[0]);
x = getfval(u);
if (x == 0.0)
break;
c_free(u);
u = execute(p->n_arg[1]);
switch (u->c_type) {
case BRK:
goto rtn;
case NXT: case EXT: case RTN:
return u;
}
c_free(u);
}
rtn:
c_free(u);
return &truecell;
}
static CELL *
Do(p) NODE *p;
{
CELL *u;
double x;
for (;;) {
u = execute(p->n_arg[0]);
switch (u->c_type) {
case BRK:
goto rtn;
case NXT: case EXT: case RTN:
return u;
}
c_free(u);
u = execute(p->n_arg[1]);
if(getfval(u) == 0.0)
break;
c_free(u);
}
rtn:
c_free(u);
return &truecell;
}
static CELL *
For(p) NODE *p;
{
CELL *u;
double x;
if (p->n_arg[0] != NULL) {
u = execute(p->n_arg[0]);
c_free(u);
}
for (;;) {
if (p->n_arg[1] != NULL) {
u = execute(p->n_arg[1]);
x = getfval(u);
c_free(u);
if (x == 0.0)
break;
}
u = execute(p->n_arg[3]);
switch (u->c_type) {
case BRK:
c_free(u);
goto rtn;
case NXT: case EXT: case RTN:
return u;
}
if (p->n_arg[2] != NULL) {
u = execute(p->n_arg[2]);
c_free(u);
}
}
rtn:
return &truecell;
}
static CELL *
Jump(p) NODE *p;
{
CELL *u;
int i;
switch ((int) p->n_arg[0]) {
case BREAK: u = &breakcell; break;
case CONTIN: u = &contcell; break;
case EXIT:
if ((int) p->n_arg[1]) {
u = execute(p->n_arg[1]);
i = (int) getfval(u);
}
else
i = 0;
closeall();
exit(i);
case RETURN:
Return(p);
u = &retcell;
break;
case NEXT: u = &nextcell; break;
}
return u;
}
static
Return(p) NODE *p;
{
CELL *u;
int i;
char *s, str[BUFSIZ];
c_free(retval);
if (p->n_arg[1] != NULL) {
if (p->n_arg[2] == NULL) {
/*
if (0) {
*/
u = execute(p->n_arg[1]);
if (u->c_type == UDF)
retval = mktmp(STR, "", 0.0);
else
retval = mktmp(u->c_type, u->c_sval, u->c_fval);
c_free(u);
}
else {
for (i = 1; p->n_arg[i] != NULL; i++) {
if (i == 1)
*str = '\0';
else
strcat(str, *OFS);
u = execute(p->n_arg[i]);
s = getsval(u);
strcat(str, s);
c_free(u);
}
/*
printf("Ret(%s)(%d)\n", str, isnum(str));
*/
if (isnum(str))
retval = mktmp(STR|NUM, str, atof(str));
else
retval = mktmp(STR, str, 0.0);
}
}
else
retval = &truecell;
}
#define MAXFRAME 100
CELL **frame[MAXFRAME];
static int framep;
static CELL *
Arg(p) NODE *p;
{
CELL *u;
int i;
u = (CELL *)p->n_arg[0];
return _Arg((int)u->c_fval);
}
CELL *
_Arg(i)
{
/*
printf("Arg(%d)\n", i);
*/
return frame[framep - 1][i];
}
static CELL *
Call(p) NODE *p;
{
CELL *u, *v, *r, **arg;
NODE *q;
int i, j, k, n;
char *emalloc();
if (framep >= MAXFRAME - 2)
error("stack frame overflow", (char *)0);
retval = &truecell;
r = (CELL *) p->n_arg[0];
if (r->c_type != FUN)
synerr("called function is not declared", (char *)0);
n = (int) r->c_fval; /* # of params */
if (n > 0) {
arg = (CELL **) emalloc(sizeof(u) * n);
for (i = 2, j = 0, k = (int) p->n_arg[1]; j < k; i++) {
u = execute(p->n_arg[i]);
/*
printf("pass, j(%d)typ(%d)\n", j, u->c_type);
*/
if (u->c_type & ARR)
v = u; /* pass by reference */
else { /* pass by value */
v = mkcell(UDF, u->c_sval, u->c_fval);
if (u->c_type != UDF) {
#if 0
v->c_type = u->c_type;
if (v->c_type & (NUM|STR))
v->c_type |= VAR;
v->c_type &= ~TMP; /* dont't free */
#else
v->c_type |= (u->c_type & (NUM|STR))|VAR;
/*v->c_type &= ~TMP;*/
#endif
/* Don't free original */
}
/*
printf("pass1, j(%d)typ(%d)\n", j, v->c_type);
*/
}
arg[j++] = v;
}
for ( ; j < n; ) /* local var */
arg[j++] = mkcell(UDF, NULL, 0.0);
}
else
arg = NULL;
frame[framep] = arg;
framep++;
r = execute(r->c_sval);
c_free(r);
framep--;
if (n > 0) {
for (j = n - 1 ; j > k; j--) { /* local var */
u = arg[j];
if (u->c_type & ARR)
a_free(u);
else
c_free(u);
}
for ( ; j >= 0; j--) {
u = arg[j];
if (!(u->c_type & ARR)) {
/* c_free(u);*/
sfree(u->c_sval);
sfree(u);
}
else {
v = execute(p->n_arg[j + 2]);
if (v->c_type == UDF) { /* copy back */
/*
printf("copy_back_UDF(%d)(%d)\n", j, u->c_type);
*/
v->c_type = u->c_type;
sfree(v->c_sval);
v->c_sval = u->c_sval;
v->c_fval = u->c_fval;
sfree(u);
}
}
}
}
sfree(arg);
/* return retval;*/
u = mktmp(retval->c_type, retval->c_sval, retval->c_fval);
return u;
}
CELL *Nulproc()
{
return &truecell;
}
CELL *
Usrfun(p) NODE *p;
{
CELL *u;
u = execute(p);
return u;
}

View File

@@ -1,43 +0,0 @@
/*
* a small awk clone
*
* (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi
*
* Absolutely no warranty. Use this software with your own risk.
*
* Permission to use, copy, modify and distribute this software for any
* purpose and without fee is hereby granted, provided that the above
* copyright and disclaimer notice.
*
* This program was written to fit into 64K+64K memory of the Minix 1.2.
*/
#include <stdio.h>
isKanji(c)
{
c &= 0xff;
return (c > 0x80 && c < 0xa0 || c > 0xdf && c < 0xfd);
}
jstrlen(s) char *s;
{
int i;
for (i = 0; *s; i++, s++)
if (isKanji(*s))
s++;
return i;
}
char *
jStrchr(s, c) char *s;
{
for ( ; *s; s++)
if (isKanji(*s))
s++;
else if (*s == c)
return s;
return NULL;
}

View File

@@ -1,353 +0,0 @@
/*
* a small awk clone
*
* (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi
*
* Absolutely no warranty. Use this software with your own risk.
*
* Permission to use, copy, modify and distribute this software for any
* purpose and without fee is hereby granted, provided that the above
* copyright and disclaimer notice.
*
* This program was written to fit into 64K+64K memory of the Minix 1.2.
*/
#include <stdio.h>
#include <ctype.h>
#include "awk.h"
extern char *srcprg; /* inline program */
extern FILE *pfp; /* program file */
int sym; /* lexical token */
int sym1; /* auxiliary lexical token */
int regexflg; /* set by parser (y.c) to indicate parsing REGEXPR */
int funflg; /* set by parser (y.c) to indicate parsing FUNCTION */
int printflg; /* set by parser (y.c) to indicate parsing PRINT */
int getlineflg; /* set by parser (y.c) to indicate parsing GETLINE */
char text[BUFSIZ]; /* lexical word */
char line[BUFSIZ]; /* program line for error message (ring buffer) */
char *linep = line; /* line pointer */
char funnam[128]; /* function name for error message */
int lineno = 1;
lex()
{
int c, d;
char *s;
if (regexflg)
return sym = scanreg();
next:
while ((c = Getc()) == ' ' || c == '\t')
;
while (c == '#')
for (c = Getc(); c != '\n'; c = Getc())
;
switch (c) {
case '\\':
if ((c = Getc()) == '\n') {
lineno++;
goto next;
}
break;
case '\n':
lineno++;
break;
}
switch (c) {
case EOF: return sym = 0;
case '+': return sym = follow2('=', '+', ADDEQ, INC, ADD);
case '-': return sym = follow2('=', '-', SUBEQ, DEC, SUB);
case '*': return sym = follow('=', MULTEQ, MULT);
case '/': return sym = follow('=', DIVEQ, DIV);
case '%': return sym = follow('=', MODEQ, MOD);
case '^': return sym = follow('=', POWEQ, POWER);
case '=': return sym = follow('=', EQ, ASSIGN);
case '!': return sym = follow2('=', '~', NE, NOMATCH, NOT);
case '&': return sym = follow('&', AND, BINAND);
case '|': sym = follow('|', OR, BINOR);
if (printflg && sym == BINOR)
sym = R_POUT;
return sym;
case '<': sym = follow2('=', '<', LE, SHIFTL, LT);
if (getlineflg && sym == LT)
sym = R_IN;
return sym;
case '>': sym = follow2('=', '>', GE, SHIFTR, GT);
if (printflg) {
switch (sym) {
case GT: sym = R_OUT; break;
case SHIFTR: sym = R_APD; break;
}
}
return sym;
case '~': return sym = MATCH; break;
case ';': case '\n': return sym = EOL;
}
if (isalpha(c) || c == '_') {
for (s = text; isalnum(c) || c == '_'; ) {
*s++ = c; c = Getc();
}
Ungetc(c);
*s = '\0';
if ((d = iskeywd(text)) == 0 &&
(d = isbuiltin(text, &sym1)) == 0) {
if (c == '(')
return sym = CALL;
else if (funflg) {
if ((sym1 = isarg(text)) != -1)
return sym = ARG;
}
}
return sym = d ? d : IDENT;
}
else if (c == '.' || (isdigit(c))) {
Ungetc(c);
return sym = scannum(text); /* NUMBER */
}
else if (c == '"')
return sym = scanstr(text); /* STRING */
return sym = c;
}
static
follow(c1, r1, r2)
{
register int c;
if ((c = Getc()) == c1)
return r1;
else {
Ungetc(c);
return r2;
}
}
static
follow2(c1, c2, r1, r2, r3)
{
register int c;
if ((c = Getc()) == c1)
return r1;
else if (c == c2)
return r2;
else {
Ungetc(c);
return r3;
}
}
static
iskeywd(s) char *s;
{
static struct { char *kw; int token; } tab[] = {
"BEGIN", BEGIN,
"END", END,
"break", BREAK,
"continue", CONTIN,
"delete", DELETE,
"do", DO,
"else", ELSE,
"exit", EXIT,
"for", FOR,
"func", FUNC,
"function", FUNC,
"getline", GETLINE,
"if", IF,
"in", IN,
"next", NEXT,
"print", PRINT,
"printf", PRINTF,
"return", RETURN,
"sprint", SPRINT,
"sprintf", SPRINTF,
"while", WHILE,
"", 0, 0
};
register int i;
for (i = 0; tab[i].token; i++)
if (strcmp(tab[i].kw, s) == 0)
break;
return tab[i].token;
}
static
isbuiltin(s, p) char *s; int *p;
{
static struct { char *kw; int type; int token; } tab[] = {
"atan2", MATHFUN, ATAN2,
"close", STRFUN, CLOSE,
"cos", MATHFUN, COS,
"exp", MATHFUN, EXP,
"gsub", SUBST, RGSUB,
"index", STRFUN, INDEX,
"int", MATHFUN, INT,
"length", STRFUN, LENGTH,
"log", MATHFUN, LOG,
"match", STRFUN, RMATCH,
"sin", MATHFUN, SIN,
"sqrt", MATHFUN, SQRT,
"rand", MATHFUN, RAND,
"srand", MATHFUN, SRAND,
"split", STRFUN, SPLIT,
"sub", SUBST, RSUB,
"substr", STRFUN, SUBSTR,
"system", STRFUN, SYSTEM,
"", 0, 0
};
register int i;
for (i = 0; tab[i].token; i++)
if (strcmp(tab[i].kw, s) == 0)
break;
*p = tab[i].token;
return tab[i].type;
}
static
scannum(s) char *s;
{
register int c;
char *strchr();
if ((c = Getc()) && strchr("+-", c) != NULL) {
*s++ = c; c = Getc();
}
while (isdigit(c)) {
*s++ = c; c = Getc();
}
if (c == '.') {
*s++ = c; c = Getc();
while (isdigit(c)) {
*s++ = c; c = Getc();
}
}
if (c && strchr("eE", c) != NULL) {
*s++ = c; c = Getc();
if (c && strchr("+-", c) != NULL) {
*s++ = c; c = Getc();
}
while (isdigit(c)) {
*s++ = c; c = Getc();
}
}
*s = '\0';
Ungetc(c);
return NUMBER;
}
static
scanstr(s) char *s;
{
register int c, i, j;
for (c = Getc(); c != EOF & c != '"'; ) {
if (c == '\\') {
switch (c = Getc()) {
case 'b': c = '\b'; break;
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
default:
if (isdigit(c)) {
for (i = j = 0; i < 3 && isdigit(c); c = Getc(), i++)
j = j * 8 + c - '0';
Ungetc(c);
c = j;
}
break;
}
}
*s++ = c;
if (isKanji(c))
*s++ = Getc();
c = Getc();
}
*s = '\0';
return STRING;
}
static
scanreg()
{
register int c;
register char *s;
for (s = text; (c = Getc()) != '/'; )
if (c == '\n')
error("newline in regular expression");
else {
if (isKanji(c) || c == '\\') {
*s++ = c; c = Getc();
}
*s++ = c;
}
*s = '\0';
return REGEXP;
}
isarrayindex()
{
int c, c2;
next:
while ((c = Getc()) == ' ' || c == '\t')
;
if (c == '\\') {
if ((c2 = Getc()) == '\n') {
lineno++;
goto next;
}
Ungetc(c2);
}
if (c != '[') Ungetc(c);
return (c == '[');
}
#define UNGET_DEPTH 2
static int unget[UNGET_DEPTH], unget_depth;
Ungetc(c)
{
if (unget_depth == UNGET_DEPTH) error("unget buffer overflow");
unget[unget_depth++] = c;
if (linep > line) {
if (--linep < line)
linep == line + BUFSIZ - 1;
}
}
Getc()
{
register int c;
char *s, *t;
if (unget_depth > 0)
c = unget[--unget_depth];
else if (srcprg)
c = *srcprg ? *srcprg++ : EOF;
else
c = fgetc(pfp);
#if 0
if (linep - line == BUFSIZ) {
printf("!!!\n");
for (s = line; *s != '\n' && ((s - line) <BUFSIZ); s++)
;
printf("***(%d)***\n", *s);
for (t = line; s < linep; )
*t++ = *++s;
}
#endif
*linep++ = c;
if ((linep - line) == BUFSIZ)
linep = line;
return c;
}

View File

@@ -1,153 +0,0 @@
/*
* a small awk clone
*
* (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi
*
* Absolutely no warranty. Use this software with your own risk.
*
* Permission to use, copy, modify and distribute this software for any
* purpose and without fee is hereby granted, provided that the above
* copyright and disclaimer notice.
*
* This program was written to fit into 64K+64K memory of the Minix 1.2.
*/
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include "awk.h"
extern char **FS, **FILENAME;
extern char record[];
extern FILE *ifp;
NODE *parse();
CELL *execute();
FILE *efopen(), *fopen();
char *strsave();
int xargc;
char **xargv;
char *srcprg;
FILE *pfp;
char *cmd;
#if 0
int iflg; /* interactive mode */
#endif
main(argc, argv, envp) char **argv, *envp;
{
char *s, *strpbrk(), *strchr();
void onint();
#ifdef DOS
_sharg(&argc, &argv);
#endif
signal(SIGINT, onint);
signal(SIGFPE, onint);
cmd = argv[0];
init();
while (--argc > 0 && (*++argv)[0] == '-')
for (s = argv[0]+1; *s; s++)
if (strcmp(argv[0], "-") == 0)
break;
else
switch (*s) {
#if 0
case 'i':
iflg++;
pfp = stdin;
interactive();
/* no return */
#endif
case 'F':
*FS = ++s;
break;
case 'f':
if (*(s+1))
s++;
else {
argc--; s = *++argv;
}
if (s == NULL) usage();
pfp = efopen(s, "r");
s += strlen(s) - 1;
break;
}
xargc = argc; xargv = argv;
if (pfp == NULL && xargc > 0) {
srcprg = *xargv++; xargc--;
}
/*
if (pfp == NULL && xargc > 0) {
if (strpbrk(xargv[0], " !$^()={}[];<>,/~") != NULL) {
sprintf(record, "%s\n", xargv[0]);
srcprg = strsave(record);
}
else {
sprintf(record, "%s.awk", xargv[0]);
if ((pfp = fopen(record, "r")) == NULL)
error("can't open %s", record);
}
xargc--; xargv++;
}
*/
if (pfp == NULL && srcprg == NULL) usage();
while (*xargv != NULL && strchr(*xargv, '=') != NULL) {
setvar(*xargv++);
xargc--;
}
initarg(cmd, xargc, xargv, envp);
if (xargc == 0) {
ifp = stdin; *FILENAME = "-";
}
parse();
closeall();
exit(0);
}
FILE *
efopen(file, mode) char *file, *mode;
{
FILE *fp, *fopen();
if ((fp = fopen(file, mode)) == NULL)
error("cannot open %s", file);
return fp;
}
error(s, t) char *s, *t;
{
extern double *NR;
fprintf(stderr, "awk: ");
fprintf(stderr, s, t);
fprintf(stderr, "\n");
if (NR != NULL) {
fprintf(stderr, "record number %g\n", *NR);
}
#ifdef DOS
closeall();
#endif
exit(1);
}
void
onint(i)
{
closeall();
exit(0x80 | i);
}
void
usage()
{
fprintf(stderr,
"usage: %s [options] [-f <rulefile> | <rules>] [inputfiles]\n", cmd);
closeall();
exit(1);
}

View File

@@ -1,149 +0,0 @@
/*
* a small awk clone
*
* (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi
*
* Absolutely no warranty. Use this software with your own risk.
*
* Permission to use, copy, modify and distribute this software for any
* purpose and without fee is hereby granted, provided that the above
* copyright and disclaimer notice.
*
* This program was written to fit into 64K+64K memory of the Minix 1.2.
*/
#include <stdio.h>
#include "awk.h"
NODE *
node0(type)
{
NODE *p;
char *emalloc();
p = (NODE *) emalloc(sizeof(*p) - sizeof(p));
p->n_type = type;
p->n_next = NULL;
return p;
}
NODE *
node1(type, arg0) NODE *arg0;
{
NODE *p;
char *emalloc();
p = (NODE *) emalloc(sizeof(*p));
p->n_type = type;
p->n_next = NULL;
p->n_arg[0] = (NODE *) arg0;
return p;
}
NODE *
node2(type, arg0, arg1) NODE *arg0, *arg1;
{
NODE *p;
char *emalloc();
p = (NODE *) emalloc(sizeof(*p) + sizeof(p) * 1);
p->n_type = type;
p->n_next = NULL;
p->n_arg[0] = (NODE *) arg0;
p->n_arg[1] = (NODE *) arg1;
return p;
}
NODE *
node3(type, arg0, arg1, arg2) NODE *arg0, *arg1, *arg2;
{
NODE *p;
char *emalloc();
p = (NODE *) emalloc(sizeof(*p) + sizeof(p) * 2);
p->n_type = type;
p->n_next = NULL;
p->n_arg[0] = (NODE *) arg0;
p->n_arg[1] = (NODE *) arg1;
p->n_arg[2] = (NODE *) arg2;
return p;
}
NODE *
node4(type, arg0, arg1, arg2, arg3) NODE *arg0, *arg1, *arg2, *arg3;
{
NODE *p;
char *emalloc();
p = (NODE *) emalloc(sizeof(*p) + sizeof(p) * 3);
p->n_type = type;
p->n_next = NULL;
p->n_arg[0] = (NODE *) arg0;
p->n_arg[1] = (NODE *) arg1;
p->n_arg[2] = (NODE *) arg2;
p->n_arg[3] = (NODE *) arg3;
return p;
}
CELL *
mkcell(type, sval, fval) char *sval; double fval;
{
CELL *p;
char *emalloc(), *strsave();
p = (CELL *) emalloc(sizeof(*p));
p->c_type = type;
if (sval == NULL)
p->c_sval = NULL;
else
p->c_sval = strsave(sval);
p->c_fval = fval;
return p;
}
#ifdef TMPCELL
#define MAXTMP 25
CELL tmpcell[MAXTMP];
#endif
CELL *
mktmp(type, sval, fval) char *sval; double fval;
{
register int i;
char *strsave();
#ifdef TMPCELL
for (i = 0; i < MAXTMP; i++)
if (tmpcell[i].c_type == 0) {
tmpcell[i].c_type = type | TMP;
tmpcell[i].c_sval = strsave(sval);
tmpcell[i].c_fval = fval;
return &tmpcell[i];
}
error("formula too complex", (char *) 0);
#else
return mkcell(type | TMP, sval, fval);
#endif
}
c_free(p) CELL *p;
{
if ((p != NULL) && (p->c_type & TMP)) {
#ifdef TMPCELL
p->c_type = 0;
sfree(p->c_sval);
p->c_sval = (char *)NULL;
p->c_fval = 0.0;
#else
if (p->c_sval != NULL) {
Free(p->c_sval);
p->c_sval = NULL;
}
p->c_type = 0;
Free(p);
p = NULL;
#endif
}
}

View File

@@ -1,627 +0,0 @@
/*
* a small awk clone
*
* (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi
*
* Absolutely no warranty. Use this software with your own risk.
*
* Permission to use, copy, modify and distribute this software for any
* purpose and without fee is hereby granted, provided that the above
* copyright and disclaimer notice.
*
* This program was written to fit into 64K+64K memory of the Minix 1.2.
*/
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifdef DOS
#include <process.h>
#endif
#include "awk.h"
#include "regexp.h"
#define MAXFLD 100
extern char **FS, **RS, **OFS, **ORS, **FILENAME;
extern double *NF, *NR;
extern double *FNR;
extern double *ARGC;
extern SYMBOL *argtab[];
extern CELL *getvar();
char *strsave(), *strcpy(), *getsval(), *jStrchr(), *strchr();
double getfval(), atof();
CELL *mkcell(), *mktmp(), *execute(), *patexec();
FILE *efopen();
extern CELL truecell, falsecell;
extern int pateval;
int infileno = 1;
FILE *ifp;
char record[BUFSIZ];
CELL *field[MAXFLD];
char *fs_str;
regexp *fs_pat;
CELL *
Getline(p) NODE *p;
{
CELL *u;
char *fnam, *s, str[BUFSIZ];
int i;
FILE *fp, *getfp();
if ((int) p->n_arg[0]) /* read into var */
s = str;
else
s = NULL;
if ((int) p->n_arg[1]) { /* file name */
u = execute(p->n_arg[1]);
fnam = getsval(u);
fp = getfp(fnam, (int) p->n_arg[2]);
c_free(u);
i = get1rec(s, fp);
}
else
i = Getrec(s);
if (s == str) {
u = execute(p->n_arg[0]);
setsval(u, str);
}
return mktmp(NUM, NULL, (double) i);
}
static
get1rec(buf, fp) char *buf; FILE *fp;
{
register int c;
register char rs, *s;
int mflg;
if (buf == NULL)
buf = record;
if ((rs = **RS) == '\0') { /* multi line record */
mflg = 1;
rs = '\n';
}
else
mflg = 0;
if (feof(fp) || (c = getc(fp)) == EOF)
return 0;
for (s = buf; ; ) {
for ( ; c != rs && c != EOF; c = getc(fp)) {
if (isKanji(c)) {
*s++ = c; c = getc(fp);
}
*s++ = c;
}
if (mflg) {
if ((c = getc(fp)) == '\n' || c == EOF)
break;
*s++ = '\n';
}
else
break;
}
*s = '\0';
#if 1
if (buf == record) {
#else
if (buf == record && c != EOF) {
#endif
mkfld(record, *FS, field);
(*NR)++;
(*FNR)++;
}
return s > buf || c != EOF ? 1 : 0;
}
Getrec(s) char *s;
{
CELL *u;
char *file, str[8];
while (ifp == stdin || infileno < (int)*ARGC) {
if (ifp == NULL) {
*FNR = 0.0;
if (infileno == (int)*ARGC)
break;
sprintf(str, "%d", infileno);
u = getvar(str, argtab);
file = getsval(u);
if (strchr(file, '=') != NULL) {
setvar(file);
infileno++;
continue;
}
else if (strcmp(file, "") == 0) {
/*
if (infileno == (int)*ARGC - 1)
ifp = stdin;
*/
infileno++;
continue;
}
else {
if (strcmp(file, "-") == 0)
ifp = stdin;
else
ifp = efopen(file, "r");
*FILENAME = file;
}
}
if (get1rec(s, ifp))
return 1;
else {
if (ifp != stdin)
fclose(ifp);
ifp = NULL;
infileno++;
}
}
ifp = stdin; /* for further "getline" */
*FILENAME = "-";
return 0; /* EOF */
}
mkfld(rec, sep, fld) char *rec, *sep; CELL *fld[];
{
char *s, *t;
char str[BUFSIZ];
int i, j, n;
int skip = 0;
if (strlen(sep) > 1)
return r_mkfld(rec, sep, fld);
if (*sep == ' ' || *sep == '\0') {
sep = " \t\n"; skip++;
}
for (i = 1, n = (int) *NF; i <= n; i++) {
sfree(fld[i]->c_sval);
sfree(fld[i]);
fld[i] = NULL;
}
for (i = 0, s = rec; ; ) {
t = str;
if (skip) {
while (*s && strchr(" \t\n", *s))
s++;
if (*s == '\0')
break;
}
while (*s && !jStrchr(sep, *s)) {
if (isKanji(*s))
*t++ = *s++;
*t++ = *s++;
}
*t = '\0';
if (isnum(str))
fld[++i] = mkcell(FLD|STR|NUM, str, atof(str));
else
fld[++i] = mkcell(FLD|STR, str, 0.0);
if (*s)
s++;
else
break;
}
*NF = (double) i;
return i;
}
static
r_mkfld(rec, sep, fld) char *rec, *sep; CELL *fld[];
{
char *s, *t;
char str[BUFSIZ];
int i, n;
regexp *mkpat();
extern int r_start, r_length;
if (strcmp(*FS, fs_str) != 0) {
sfree(fs_str); sfree(fs_pat);
fs_str = strsave(*FS);
fs_pat = mkpat(fs_str);
}
for (i = 1, n = (int) *NF; i <= n; i++) {
sfree(fld[i]->c_sval);
sfree(fld[i]);
fld[i] = NULL;
}
for (i = 0, s = rec, t = str; *s; ) {
if (match(fs_pat, s)) {
for (n = r_start; --n > 0; )
*t++ = *s++;
}
else {
while (*s)
*t++ = *s++;
}
*t = '\0';
t = str;
fld[++i] = mkcell(FLD|STR, str, 0.0);
if (*s)
s += r_length;
}
*NF = (double) i;
return i;
}
mkrec(u) CELL *u;
{
register char *s, *t;
register int i, j;
for (j = (int)*NF, i = 1; i <= j; i++)
if (field[i] == u)
break;
if (i > j) {
for ( ; i < MAXFLD; i++)
if (field[i] == u)
break;
if (i == MAXFLD)
error("too many field (%d)", i);
*NF = (double)i;
}
for (t = record, i = 1, j = (int) *NF; i <= j; i++) {
if (i > 1)
*t++ = **OFS;
for (s = getsval(field[i]); *s; )
*t++ = *s++;
}
*t++ = '\0';
}
CELL *
Field(p) NODE *p;
{
CELL *u;
int i, j;
u = execute(p->n_arg[0]);
i = (int) getfval(u);
c_free(u);
j = (int)*NF;
if (i > j)
for (++j; j <= i; j++) {
if (field[j] == NULL)
field[j] = mkcell(FLD|STR, "", 0.0);
}
return field[i];
}
CELL *
P1stat(p) NODE *p;
{
CELL *u;
double x;
pateval++;
u = execute(p->n_arg[0]);
pateval = 0;
x = getfval(u);
c_free(u);
if (x != 0.0)
u = execute(p->n_arg[1]);
else
u = &truecell;
return u;
}
CELL *
P2stat(p) NODE *p;
{
static stat = 0;
CELL *u, *v;
double x;
switch (stat) {
case 0:
pateval++;
u = execute(p->n_arg[0]);
pateval = 0;
x = getfval(u);
c_free(u);
if (x == 0.0) {
u = &truecell; break;
}
else
stat++;
/* fall through */
case 1:
u = execute(p->n_arg[2]);
c_free(u);
pateval++;
u = execute(p->n_arg[1]);
pateval = 0;
x = getfval(u);
if (x != 0.0)
stat = 0;
break;
default:
u = &truecell;
break;
}
return u;
}
CELL *
Print0()
{
/*
int i, j;
char *s, str[BUFSIZ];
for (*str = '\0', i = 1, j = (int) *NF; i <= j; i++) {
if (i > 1)
strcat(str, *OFS);
s = getsval(field[i]);
strcat(str, s);
}
strcat(str, *ORS);
fputs(str, stdout);
*/
fprintf(stdout, "%s%s", record, *ORS);
return &truecell;
}
char *
format(t, p) char *t; NODE *p;
{
CELL *u, *v;
char *r, *s, *s0, fmt[BUFSIZ];
double x;
int i;
u = execute(p->n_arg[2]);
s = s0 = getsval(u);
/*
printf("fmt(%s)\n", s);
*/
for (i = 3; *s; s++) {
if (isKanji(*s)) {
*t++ = *s++; *t++ = *s; continue;
}
if (*s != '%') {
*t++ = *s; continue;
}
else if (*(s + 1) == '%') {
*t++ = *s++; continue;
}
for (r = fmt, *r++ = *s++; *r++ = *s; s++) {
if (strchr("%cdefgosux", *s))
break;
}
*r = '\0';
if (p->n_arg[i] == NULL)
error("not enough args in printf(%s)", s0);
v = execute(p->n_arg[i++]);
if (*s == 's')
r = getsval(v);
else
x = getfval(v);
/*
printf("val(%d)(%s)\n", v->c_type, v->c_sval);
*/
switch (*s) {
case 'c':
sprintf(t, fmt, (int) x);
break;
case 'd':
if (*(s - 1) != 'l') {
*--r = 'l'; *++r = 'd'; *++r = '\0';
}
sprintf(t, fmt, (long) x);
break;
case 'e': case 'f': case 'g':
sprintf(t, fmt, x);
break;
case 'o': case 'u': case 'x':
if (*(s - 1) == 'l')
sprintf(t, fmt, (long) x);
else
sprintf(t, fmt, (int) x);
break;
case 's':
/*r = getsval(v);*/
sprintf(t, fmt, r);
break;
default:
strcpy(t, fmt);
break;
}
c_free(v);
t += strlen(t);
}
c_free(u);
*t = '\0';
}
#define MAXFILE 10
struct {
char *f_name; /* file name */
FILE *f_fp;
int f_type;
} filetab[MAXFILE];
FILE *
getfp(file, type) char *file;
{
register int i;
register char *name, *mode;
char *awktmp();
FILE *fp, *efopen(), *epopen();
for (i = 0; i < MAXFILE; i++)
if (filetab[i].f_name && strcmp(filetab[i].f_name, file) == 0)
return filetab[i].f_fp;
for (i = 0; i < MAXFILE; i++)
if (!filetab[i].f_fp)
break;
if (i == MAXFILE)
error("too many files to open");
name = file;
switch (type) {
case R_OUT: mode = "w"; break;
case R_APD: mode = "a"; break;
case R_POUT:
#ifdef DOS
name = awktmp(i); mode = "w"; /* MS-DOS */
#else
fp = epopen(file, "w");
goto g1;
#endif
break;
case R_IN: mode = "r"; break;
case R_PIN:
#ifdef DOS
{
int savefd, fd, result;
name = awktmp(i);
if ((fd = open(name,
O_WRONLY|O_TEXT|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE)) == -1)
error("can't open %s", name);
savefd = dup(1); dup2(fd, 1); close(fd);
if ((result =
system(file)) == -1)
error("can't exec %s", file);
dup2(savefd, 1); close(savefd); close(fd);
mode = "r";
}
#else
fp = epopen(file,"r");
goto g1;
#endif
break;
}
fp = efopen(name, mode);
g1:
filetab[i].f_name = strsave(file);
filetab[i].f_type = type;
filetab[i].f_fp = fp;
return fp;
}
closeall()
{
register int i;
for (i = 0; i < MAXFILE; i++)
close1(i);
}
CELL *
Close(s) char *s;
{
register int i;
for (i = 0; i < MAXFILE; i++)
if (strcmp(s, filetab[i].f_name) == 0) {
close1(i);
break;
}
i = (i == MAXFILE) ? 0 : 1;
return mktmp(NUM, NULL, (double) i);
}
static
close1(i)
{
int fd, result, savefd;
char *awktmp();
if (filetab[i].f_fp == NULL)
return;
switch (filetab[i].f_type) {
case R_PIN:
#ifdef DOS
fclose(filetab[i].f_fp);
unlink(awktmp(i));
#else
pclose(filetab[i].f_fp);
#endif
break;
case R_IN: case R_OUT: case R_APD:
fclose(filetab[i].f_fp);
break;
case R_POUT:
#ifdef DOS
fclose(filetab[i].f_fp);
if ((fd = open(awktmp(i), O_RDONLY)) == NULL)
error("can't open %s", awktmp(i));
savefd = dup(0);
dup2(fd, 0);
close(fd);
if ((result =
system(filetab[i].f_name)) == -1)
/*
spawnl(P_WAIT, "/usr/bin/sh", "sh", "-c", filetab[i].f_name, (char *) 0)) == -1)
fprintf(stderr, "can't spawn /bin/sh\n");
*/
error("can't exec %s", filetab[i].f_name);
dup2(savefd, 0);
close(savefd);
unlink(awktmp(i));
#else
pclose(filetab[i].f_fp);
#endif
break;
}
sfree(filetab[i].f_name);
filetab[i].f_type = 0;
filetab[i].f_name = NULL;
filetab[i].f_fp = NULL;
}
#ifndef DOS
FILE *
epopen(file, mod) char *file, *mod;
{
FILE *fp, *popen();
if ((fp = popen(file, mod)) == NULL)
error("can't poen %s", file);
return fp;
}
#endif
static char *
awktmp(i)
{
static char str[16];
sprintf(str, "awk000%02d.tmp", i);
return str;
}
Index(s, t) char *s, *t;
{
register char *u, *v;
register int i;
for (i = 1; *s; s++, i++) {
for (u = s, v = t; *v; u++, v++) {
if (isKanji(*v)) {
if (*u != *v)
break;
u++; v++;
}
if (*u != *v)
break;
}
if (*v == '\0')
return i;
if (isKanji(*s))
s++;
}
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,23 +0,0 @@
/*
* Definitions etc. for regexp(3) routines.
*
* Caveat: this is V8 regexp(3) [actually, a reimplementation thereof],
* not the System V one.
*/
#define ushort unsigned short
#define CHARBITS 0xffff
#define NSUBEXP 10
typedef struct regexp {
ushort *startp[NSUBEXP];
ushort *endp[NSUBEXP];
ushort regstart; /* Internal use only. */
ushort reganch; /* Internal use only. */
ushort *regmust; /* Internal use only. */
int regmlen; /* Internal use only. */
ushort program[1]; /* Unwarranted chumminess with compiler. */
} regexp;
extern regexp *regcomp();
extern int regexec();
extern int regsub();
extern int regerror();

View File

@@ -1,703 +0,0 @@
/*
* a small awk clone
*
* (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi
*
* Absolutely no warranty. Use this software with your own risk.
*
* Permission to use, copy, modify and distribute this software for any
* purpose and without fee is hereby granted, provided that the above
* copyright and disclaimer notice.
*
* This program was written to fit into 64K+64K memory of the Minix 1.2.
*/
#include <stdio.h>
#include <ctype.h>
#include "awk.h"
#include "regexp.h"
#define PI 3.14159265358979323846
#define HASHSIZE 50
#define MAXFIELD 100
double atof();
char *getsval(), *jStrchar();
extern CELL *execute(), *_Arg();
extern char record[];
extern CELL *field[];
extern CELL truecell, falsecell;
extern prmflg;
SYMBOL *hashtab[HASHSIZE];
SYMBOL *funtab[HASHSIZE];
SYMBOL *argtab[HASHSIZE];
SYMBOL *envtab[HASHSIZE];
char *strsave(), *emalloc(), *strchr();
CELL *lookup(), *install(), *_install(), *mkcell(), *mktmp(), *getvar();
char **FS, **RS, **OFS, **ORS, **OFMT, **FILENAME;
char **SUBSEP;
double *NR, *NF;
double *FNR, *ARGC, *RSTART, *RLENGTH;
init()
{
FS = &install("FS", VAR|STR, " ", 0.0, hashtab)->c_sval;
RS = &install("RS", VAR|STR, "\n", 0.0, hashtab)->c_sval;
OFS = &install("OFS", VAR|STR , " ", 0.0, hashtab)->c_sval;
ORS = &install("ORS", VAR|STR, "\n", 0.0, hashtab)->c_sval;
OFMT = &install("OFMT", VAR|STR, "%.6g", 0.0, hashtab)->c_sval;
NR = &install("NR", VAR|NUM, (char *)NULL, 0.0, hashtab)->c_fval;
NF = &install("NF", VAR|NUM, (char *)NULL, 0.0, hashtab)->c_fval;
FILENAME = &install("FILENAME", VAR|STR, (char *)NULL, 0.0, hashtab)->c_sval;
install("PI", VAR|NUM, (char *)NULL, PI, hashtab);
field[0] = mkcell(REC|STR, (char *)NULL, 0.0); /* $0 */
field[0]->c_sval = record;
SUBSEP = &install("SUBSEP", VAR|STR, "\034", 0.0, hashtab)->c_sval;
FNR = &install("FNR", VAR|NUM, (char *)NULL, 0.0, hashtab)->c_fval;
RSTART = &install("RSTART", VAR|NUM, (char *)NULL, 0.0, hashtab)->c_fval;
RLENGTH = &install("RLENGTH", VAR|NUM, (char *)NULL, 0.0, hashtab)->c_fval;
}
setvar(s) char *s;
{
CELL *u;
char *t;
for (t = s; *t && *t != '='; t++)
;
*t++ = '\0';
if ((u = lookup(s, hashtab)) == (CELL *)NULL) {
if (isnum(t))
install(s, VAR|NUM|STR, t, atof(t), hashtab);
else
install(s, VAR|STR, t, 0.0, hashtab);
}
else {
if (isnum(t))
setfval(u, atof(t));
else
setsval(u, t);
}
}
initarg(arg0, argc, argv, envp) char *arg0, **argv, **envp;
{
CELL *u;
register int i;
register char str[4], *p;
ARGC = &install("ARGC", VAR|NUM, (char *)NULL, (double)argc+1, hashtab)->c_fval;
u = install("ARGV", ARR, (char *)NULL, 0.0, hashtab);
u->c_sval = (char *) argtab;
install("0", VAR|STR, arg0, 0.0, argtab);
for (i = 0; i < argc; i++) {
sprintf(str, "%d", i+1);
if (isnum(argv[i]))
install(str, VAR|STR|NUM, argv[i], atof(argv[i]), argtab);
else
install(str, VAR|STR, argv[i], 0.0, argtab);
}
u = install("ENVIRON", ARR, (char *)NULL, 0.0, hashtab);
u->c_sval = (char *) envtab;
for (i = 0; envp[i] && *envp[i]; i++) {
if ((p = strchr(envp[i], '=')) != NULL) {
*p = 0;
if (isnum(p+1))
install(envp[i], VAR|STR|NUM, p+1, atof(p+1), envtab);
else
install(envp[i], VAR|STR, p+1, 0.0, envtab);
*p = '=';
}
}
}
static
hash(s) unsigned char *s;
{
register unsigned int h;
for (h = 0; *s; )
h += *s++;
return h % HASHSIZE;
}
CELL *
lookup(s, h) char *s; SYMBOL *h[];
{
register SYMBOL *p;
for (p = h[hash(s)]; p; p = p->s_next)
if (strcmp(s, p->s_name) == 0)
return p->s_val;
return (CELL *)NULL;
}
static CELL *
install(name, type, sval, fval, h) char *name, *sval; double fval; SYMBOL *h[];
{
CELL *u;
if ((u = lookup(name, h)) == (CELL *)NULL)
u = _install(name, type, sval, fval, h);
else
error("%s is doubly defined", name);
return u;
}
static CELL *
_install(name, type, sval, fval, h) char *name, *sval; double fval; SYMBOL *h[];{
register SYMBOL *p;
CELL *u;
int hval;
p = (SYMBOL *) emalloc(sizeof(*p));
u = (CELL *) emalloc(sizeof(*u));
p->s_name = strsave(name);
p->s_val = u;
hval = hash(name);
p->s_next = h[hval];
h[hval] = p;
u->c_type = type;
u->c_sval = strsave(sval);
#if 0
if (!(type & NUM) && isnum(sval)) {
u->c_fval = atof(sval);
u->c_type |= NUM;
}
else
#endif
u->c_fval = fval;
return u;
}
CELL *
getvar(s, h, typ) char *s; SYMBOL *h[];
{
CELL *u;
SYMBOL *p;
char *t;
int i, hval;
if ((u = lookup(s, h)) == (CELL *)NULL) {
if (prmflg) {
u = _install(s, UDF, "", 0.0, h);
goto rtn;
}
else if (typ & ARR) {
t = emalloc(sizeof(SYMBOL *) * HASHSIZE);
for (i = 0; i < HASHSIZE; i++)
((SYMBOL **) t)[i] = (SYMBOL *)NULL;
u = (CELL *) emalloc(sizeof(*u));
u->c_type = typ;
u->c_sval = t;
u->c_fval = 0.0;
p = (SYMBOL *) emalloc(sizeof(*p));
p->s_name = strsave(s);
p->s_val = u;
hval = hash(s);
p->s_next = h[hval];
h[hval] = p;
}
else
u = _install(s, typ, "", 0.0, h);
}
else if (!prmflg && (u->c_type == UDF) && (typ != UDF)) {
/* fix up local_var/forward_function */
if (typ == ARR) {
/*
printf("getvar_correct_to_array\n");
*/
u->c_type = typ;
sfree(u->c_sval);
u->c_sval = emalloc(sizeof(SYMBOL *) * HASHSIZE);
for (i = 0; i < HASHSIZE; i++)
((SYMBOL **) u->c_sval)[i] = (SYMBOL *)NULL;
u->c_fval = 0.0;
}
else if (typ != UDF) {
u->c_type = typ;
}
}
rtn:
return u;
}
fixarray(u) CELL *u;
{
int i;
if (u->c_type == UDF) { /* fix up local var */
/*
printf("fixarray\n");
*/
u->c_type = ARR;
sfree(u->c_sval);
u->c_sval = emalloc(sizeof(SYMBOL *) * HASHSIZE);
for (i = 0; i < HASHSIZE; i++)
((SYMBOL **) u->c_sval)[i] = (SYMBOL *)NULL;
u->c_fval = 0.0;
}
}
a_free(u) CELL *u;
{ /* free local array */
SYMBOL **h, *q, *r;
CELL *v;
int i;
if (!(u->c_type & ARR))
error("try to free non array variable", (char *)0);
h = (SYMBOL **) u->c_sval;
for (i = 0; i < HASHSIZE; i++)
for (q = h[i]; q; q = r) {
r = q->s_next;
sfree(q->s_name);
v = q->s_val; /* CELL */
c_free(v);
sfree(q); /* SYMBOL */
}
sfree(u->c_sval); /* symbol table */
c_free(u);
}
CELL *
Array(p) NODE *p;
{
CELL *u;
char str[BUFSIZ];
int i, n;
CELL *v;
u = (CELL *) p->n_arg[0];
if (u->c_type == POS) {
i = (int)u->c_fval;
/*
printf("**ARG_ARRAY(%d)*\n", i);
*/
u = _Arg(i);
if (u->c_type == UDF) { /* fix up local array */
/*
printf("local_var_to_array\n");
*/
fixarray(u);
}
}
else if (!(u->c_type & ARR))
error("non array refference");
arrayelm(p, str);
u = getvar(str, u->c_sval, VAR|NUM|STR); /* "rtsort in AWK book */
return u;
}
static
arrayelm(p, s) NODE *p; char *s;
{
CELL *u;
int i, n;
char *t;
/*
char *tt = s;
*/
n = (int) p->n_arg[1] + 2;
for (i = 2; i < n; i++) {
if (i > 2)
*s++ = **SUBSEP;
u = execute(p->n_arg[i]);
for (t = getsval(u); *t; )
*s++ = *t++;
c_free(u);
}
*s = '\0';
/*
printf("array_elm(%s)\n", tt);
*/
}
CELL *
Element(p) NODE *p;
{
char str[BUFSIZ];
arrayelm(p, str);
return mktmp(STR, str, 0.0);
}
CELL *
Delete(p) NODE *p;
{
CELL *u;
char str[BUFSIZ];
int i;
SYMBOL *q, *r, **h;
u = (CELL *) p->n_arg[0];
if (!(u->c_type & ARR))
error("can't delete non array variable");
arrayelm(p, str);
h = (SYMBOL **) u->c_sval;
for (r = (SYMBOL *)NULL, i = hash(str), q = h[i]; q; r = q, q = q->s_next)
if (strcmp(str, q->s_name) == 0)
break;
if (q) {
sfree(q->s_val->c_sval);
sfree(q->s_name);
if (r)
r->s_next = q->s_next;
if (q == h[i])
h[i] = (SYMBOL *)NULL;
}
return &truecell;
}
CELL *
In(p) NODE *p;
{
SYMBOL **h, *q;
CELL *u, *v;
char *s;
int i;
u = (CELL *) p->n_arg[1]; /* array */
if (!(u->c_type & ARR))
error("%s is not an array", u->c_sval);
h = (SYMBOL **) u->c_sval;
if (u->c_sval != (char *)NULL) {
v = execute(p->n_arg[0]); /* var */
s = getsval(v);
for (i = 0; i < HASHSIZE; i++)
for (q = h[i]; q; q = q->s_next) {
if (strcmp(s, q->s_name) == 0) {
c_free(v);
return &truecell;
}
}
c_free(v);
}
return &falsecell;
}
CELL *
Split(p) NODE *p;
{
CELL *u, *v, *w;
char *s, *t, *h, *name, *sep;
int i, n, skip;
char elm[8], str[BUFSIZ];
static char *s_str;
static regexp *s_pat;
regexp *mkpat();
extern int r_start, r_length;
n = (int) p->n_arg[1];
if (n > 1) {
u = execute(p->n_arg[2]);
s = getsval(u); /* str */
v = execute(p->n_arg[3]); /* array */
if (!(v->c_type & ARR)) {
/*
printf("Split fix_to_array(%d)\n", v->c_type);
*/
if (v->c_type == UDF) /* fix up local array */
fixarray(v);
else
error("split to non array variable", (char *)0);
}
h = v->c_sval;
c_free(v);
if (n > 2) {
v = execute(p->n_arg[4]);
sep = getsval(v);
}
else {
v = (CELL *)NULL;
sep = *FS;
}
if (strlen(sep) > 1) { /* reg_exp */
if (strcmp(sep, s_str) != 0) {
sfree(s_str); sfree(s_pat);
s_str = strsave(sep);
s_pat = mkpat(s_str);
}
for (i = 0, t = str; *s; ) {
if (match(s_pat, s)) {
for (n = r_start; --n > 0; )
*t++ = *s++;
}
else {
while(*s)
*t++ = *s++;
}
*t = '\0';
t = str;
sprintf(elm, "%d", ++i);
w = getvar(elm, h, VAR);
if (isnum(str))
setfval(w, atof(str));
else
setsval(w, str);
if (*s)
s += r_length;
}
}
else {
skip = *sep == ' ';
for (i = 0; t = str, *s; ) {
if (skip)
while (jStrchr(" \t\n", *s))
s++;
if (!(*s))
break;
while (*s && !jStrchr(sep, *s)) {
if (isKanji(*s))
*t++ = *s++;
*t++ = *s++;
}
*t = '\0';
sprintf(elm, "%d", ++i);
w = getvar(elm, h, VAR);
if (isnum(str))
setfval(w, atof(str));
else
setsval(w, str);
if (*s && !skip)
s++;
}
}
c_free(v); /* sep */
c_free(u); /* str may be CATed */
}
else
i = 0;
return mktmp(NUM, (char *)NULL, (double) i);
}
CELL *
Forin(p) NODE *p;
{
CELL *u, *v;
SYMBOL **h, *q;
char *name;
int i;
u = execute(p->n_arg[1]);
if (!(u->c_type & ARR))
synerr(
"non array variable is specified in 'for (. in var)'", (char *)0);
h = (SYMBOL **) u->c_sval;
c_free(u);
u = execute(p->n_arg[0]);
if (u->c_type == UDF) {
/*
printf("Forin_fix_to_VAR|NUM\n");
*/
u->c_type = VAR|NUM;
}
if (!(u->c_type & VAR))
error("'for (VAR in .)' is not variable (%d)", name, u->c_type);
for (i = 0; i < HASHSIZE; i++) {
for (q = h[i]; q; q = q->s_next) {
setsval(u, q->s_name);
v = execute(p->n_arg[2]);
c_free(v);
}
}
c_free(u);
return &truecell;
}
char *
strsave(s) char *s;
{
register int n;
char *emalloc(), *strcpy();
if (s == (char *)NULL)
return (char *)NULL;
n = strlen(s) + 1;
return strcpy(emalloc(n), s);
}
sfree(p) char *p;
{
if (p != (char *)NULL)
Free(p);
}
isnum(s) char *s;
{
char *strchr();
if (s == NULL || *s == '\0' || !strcmp(s, "."))
return 0;
if (*s && strchr("+-", *s) != (char *)NULL)
s++;
if (*s == '\0')
return 0;
while (isdigit(*s))
s++;
if (*s == '.') {
s++;
while (isdigit(*s))
s++;
}
if (*s && strchr("eE", *s) != (char *)NULL) {
s++;
if (*s == '\0')
return 0;
if (*s && strchr("+-", *s) != (char *)NULL)
s++;
while (isdigit(*s))
s++;
}
return *s == '\0';
}
setfval(u, f) CELL *u; double f;
{
if (u->c_type == UDF) { /* fix up local var */
/*
printf("setfval_fix_to_VAR\n");
*/
u->c_type |= VAR;
}
if (u->c_type & (VAR|FLD|REC|TMP)) {
u->c_type &= ~STR;
u->c_type |= NUM;
sfree(u->c_sval);
u->c_sval = (char *)NULL;
u->c_fval = f;
if (u->c_type & FLD)
mkrec(u);
}
else
fprintf(stderr, "assign to nonvariable (%d)\n", u->c_type);
}
setsval(u, s) CELL *u; char *s;
{
double atof();
if (u->c_type == UDF) { /* fix up local var */
/*
printf("setsval_fix_to_VAR\n");
*/
u->c_type |= VAR;
}
if (u->c_type & (VAR|FLD|REC|TMP)) {
u->c_type &= ~NUM;
u->c_type |= STR;
sfree(u->c_sval);
u->c_sval = strsave(s);
#if 0 /* "table2" in AWK book */
if (isnum(u->c_sval)) {
u->c_fval = atof(u->c_sval);
u->c_type |= NUM;
}
else
#endif
u->c_fval = 0.0;
if (u->c_type & FLD)
mkrec(u);
}
else
fprintf(stderr, "assign to constant (%d)\n", u->c_type);
}
double
getfval(u) CELL *u;
{
double x, atof();
if (u->c_type == UDF) { /* local var */
u->c_type |= VAR|STR|NUM;
u->c_sval = strsave("");
x = u->c_fval = 0.0;
}
else if (u->c_type & NUM)
x = u->c_fval;
#if 1
else {
x = atof(u->c_sval);
#else
else {
if (isnum(u->c_sval))
x = atof(u->c_sval);
else
x = 0.0;
#endif
}
return x;
}
char *
getsval(u) CELL *u;
{
char *s, str[80];
if (u->c_type & STR)
s = u->c_sval;
else if (u->c_type & NUM) {
/* if (u->c_fval >= -2147483648.0 && u->c_fval <= 2147483647.0)*/
if ((long)u->c_fval == u->c_fval)
s = "%.16g";
else
s = *OFMT;
sprintf(str, s, u->c_fval);
sfree(u->c_sval);
s = u->c_sval = strsave(str);
}
#if 1
else if (u->c_type == UDF) { /* local var */
/*
printf("getsval_fix_to_VAR|STR\n");
*/
u->c_type |= VAR|STR|NUM;
s = u->c_sval = strsave("");
u->c_fval = 0.0;
}
#endif
else
fprintf(stderr, "abnormal value (STR|NUM == 0)(%d)\n", u->c_type);
return s;
}
char *
emalloc(n) unsigned n;
{
char *p;
#if 0
char far *_fmalloc();
#else
char *malloc();
#endif
#if 0
if ((p = _fmalloc(n)) == (char *)NULL)
#else
if ((p = malloc(n)) == (char *)NULL)
#endif
error("memory over");
return p;
}
Free(s) char *s;
{
#if DOS
void _ffree();
_ffree(s);
#else
free(s);
#endif
}

File diff suppressed because it is too large Load Diff