Remove obsolete implementation of awk.
This commit is contained in:
parent
d106968d77
commit
55129194a3
|
|
@ -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
Loading…
Reference in New Issue
Block a user