Remove obsolete implementation of awk.
This commit is contained in:
@@ -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
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
make clean
|
||||
make && make install
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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();
|
||||
@@ -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
|
||||
}
|
||||
1086
commands/awk.old/y.c
1086
commands/awk.old/y.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user